mrd_prime 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d17143e5a145a9c98fc99c910d98bfb27a9fe6a097998ce57685e14a6a0e28db
4
+ data.tar.gz: 8f3ad79e530c346e598298c94605a39f8c4460e7eef05e5a6bc3c86465fba9ee
5
+ SHA512:
6
+ metadata.gz: 6f18db85331ff59361692fb557ce7811fdd443e07a86eb20493f295d0d64ab25e7d4cfcfa78641a6fc70f638f69fe72d0dd185cccefdb1556e2b5f63ed2b2fd9
7
+ data.tar.gz: f77022bba5faa89d1778316cf06fe5ffb720088bcd6b23990af4deed6a71db6092f85caaf466e7e27dd90da53effa651d321f3953374c3d9b039f7de875fcff4
@@ -0,0 +1,23 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+
13
+ .vscode/*
14
+ !.vscode/settings.json
15
+ !.vscode/tasks.json
16
+ !.vscode/launch.json
17
+ !.vscode/extensions.json
18
+ *.code-workspace
19
+
20
+ # Local History for Visual Studio Code
21
+ .history/
22
+
23
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,6 @@
1
+ ---
2
+ language: ruby
3
+ cache: bundler
4
+ rvm:
5
+ - 2.7.0
6
+ before_install: gem install bundler -v 2.1.4
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mrd_prime.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
7
+ gem "rspec", "~> 3.0"
@@ -0,0 +1,62 @@
1
+ # MrdPrime
2
+
3
+ Miller-Rabin Prime Number Determination.
4
+
5
+ A small number(~2^81) makes a definitive decision.
6
+ A large number will fallback to `OpenSSL::BN::prime?`.
7
+
8
+ ### About the amount of calculation
9
+
10
+ In order to reduce the amount of calculation, a decision is made using the minimum amount of calculation.
11
+ For example, just testing on 2 will determine up to 2047.
12
+ Testing on 2 and 3, gives a decision up to 1373653.
13
+
14
+ https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test#Testing_against_small_sets_of_bases
15
+ "if n < 3,317,044,064,679,887,385,961,981,
16
+ it is enough to test a = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, and 41.
17
+ and the result will be deterministic."
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ ```
24
+ gem 'mrd_prime'
25
+ ```
26
+
27
+ And then execute:
28
+
29
+ ```
30
+ $ bundle install
31
+ ```
32
+
33
+ Or install it yourself as:
34
+
35
+ ```
36
+ $ gem install mrd_prime
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ```
42
+ require 'mrd_prime'
43
+
44
+ small_number = (2**79 + 23)
45
+
46
+ puts( small_number.mrd_prime? ) #=> true
47
+ ```
48
+
49
+ If you want to use the name `prime?`, you can alias it.
50
+
51
+ ```rb
52
+ class Integer
53
+ alias_method :prime?, :mrd_prime?
54
+ end
55
+
56
+ puts( (2**79 + 23).prime? ) #=> true
57
+ ```
58
+
59
+ ## Contributing
60
+
61
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Matsuyanagi/mrd_prime .
62
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mrd_prime"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,79 @@
1
+ require "mrd_prime/version"
2
+
3
+ require 'openssl'
4
+
5
+ class Integer
6
+ # Returns true if +self+ is a prime number, else returns false.
7
+ #
8
+ # https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
9
+ # https://oeis.org/A014233/list
10
+ #
11
+ # "if n < 3,317,044,064,679,887,385,961,981,
12
+ # it is enough to test a = 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, and 41.
13
+ # and the result will be deterministic."
14
+ #
15
+ def mrd_prime?
16
+
17
+ return false if self < 2
18
+ return true if self < 4
19
+ return false if self.even?
20
+
21
+ prime_and_max = {
22
+ 2 => 8321, # 2047. Strong pseudoprimes to base 2, [ 2047(=23x89), 3277(=29x113), 4033(=37x109), 4681(=31x151), 8321(=53x157) ] ~ 4681 is divided by a small prime number.
23
+ 3 => 1373653,
24
+ 5 => 25326001,
25
+ 7 => 3215031751,
26
+ 11 => 2152302898747,
27
+ 13 => 3474749660383,
28
+ 17 => 341550071728321,
29
+ 19 => 341550071728321,
30
+ 23 => 3825123056546413051,
31
+ 29 => 3825123056546413051,
32
+ 31 => 3825123056546413051,
33
+ 37 => 318665857834031151167461,
34
+ 41 => 3317044064679887385961981,
35
+ }
36
+
37
+ last_p = 1
38
+ prime_and_max.each do |p,m|
39
+ return true if self == p
40
+ return false if self % p == 0
41
+ last_p = p
42
+ end
43
+ return true if self < last_p * last_p
44
+
45
+ p_1 = self - 1
46
+
47
+ d = p_1
48
+ while d.even?
49
+ d >>= 1
50
+ end
51
+
52
+ prime_and_max.each do |a,m|
53
+ x = a.pow( d, self )
54
+
55
+ if x == 1
56
+ return true if self < m
57
+ next
58
+ end
59
+
60
+ td = d
61
+ while td != p_1 && x != p_1
62
+ x = x.pow( 2, self )
63
+ td <<= 1
64
+ end
65
+
66
+ if td == p_1
67
+ return false
68
+ else
69
+ return true if x == p_1 && self < m
70
+ end
71
+
72
+ end
73
+
74
+ # OpenSSL fallback
75
+ # return true
76
+ return OpenSSL::BN.new( self ).prime?
77
+ end
78
+ end
79
+
@@ -0,0 +1,3 @@
1
+ module MrdPrime
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'lib/mrd_prime/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "mrd_prime"
5
+ spec.version = MrdPrime::VERSION
6
+ spec.authors = ["Matsuyanagi"]
7
+ spec.email = ["1475814+Matsuyanagi@users.noreply.github.com"]
8
+
9
+ spec.summary = %q{A definitive Miller-Rabin prime determination test for small numbers.}
10
+ spec.description = %q{A definitive Miller-Rabin prime determination test for small numbers (~2^81). For large numbers, fall back to OpenSSL::BN.}
11
+ spec.homepage = "https://github.com/Matsuyanagi/mrd_prime"
12
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+ spec.license = "MIT"
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+ spec.metadata["source_code_uri"] = "https://github.com/Matsuyanagi/mrd_prime"
17
+ spec.metadata["changelog_uri"] = "https://github.com/Matsuyanagi/mrd_prime"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
23
+ end
24
+
25
+ spec.require_paths = ["lib"]
26
+ spec.add_dependency 'openssl', '~> 2'
27
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mrd_prime
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Matsuyanagi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-08-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: openssl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2'
27
+ description: A definitive Miller-Rabin prime determination test for small numbers
28
+ (~2^81). For large numbers, fall back to OpenSSL::BN.
29
+ email:
30
+ - 1475814+Matsuyanagi@users.noreply.github.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - ".rspec"
37
+ - ".travis.yml"
38
+ - Gemfile
39
+ - README.md
40
+ - Rakefile
41
+ - bin/console
42
+ - bin/setup
43
+ - lib/mrd_prime.rb
44
+ - lib/mrd_prime/version.rb
45
+ - mrd_prime.gemspec
46
+ homepage: https://github.com/Matsuyanagi/mrd_prime
47
+ licenses:
48
+ - MIT
49
+ metadata:
50
+ homepage_uri: https://github.com/Matsuyanagi/mrd_prime
51
+ source_code_uri: https://github.com/Matsuyanagi/mrd_prime
52
+ changelog_uri: https://github.com/Matsuyanagi/mrd_prime
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.0
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.1.4
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: A definitive Miller-Rabin prime determination test for small numbers.
72
+ test_files: []