Module: Obfuskey::Math
- Defined in:
- lib/obfuskey/math.rb
Class Method Summary collapse
- .extended_gcd(a, b) ⇒ Object
- .factor(n) ⇒ Object
- .mod_inv(base, mod) ⇒ Object
- .next_prime(n) ⇒ Object
- .prime?(n) ⇒ Boolean
- .small_strong_pseudoprime(n) ⇒ Object
- .strong_pseudoprime(n, base = 2) ⇒ Object
- .trial_division(n) ⇒ Object
Class Method Details
.extended_gcd(a, b) ⇒ Object
85 86 87 88 89 |
# File 'lib/obfuskey/math.rb', line 85 def extended_gcd(a, b) return [a, 1, 0] if b.zero? g, x1, y1 = extended_gcd(b, a % b) [g, y1, x1 - (a / b) * y1] end |
.factor(n) ⇒ Object
5 6 7 8 9 10 11 12 13 |
# File 'lib/obfuskey/math.rb', line 5 def factor(n) s = 0 d = n - 1 while d.even? s += 1 d /= 2 end [s, d] end |
.mod_inv(base, mod) ⇒ Object
79 80 81 82 83 |
# File 'lib/obfuskey/math.rb', line 79 def mod_inv(base, mod) g, x, _ = extended_gcd(base % mod, mod) raise ArgumentError, "base and mod are not coprime" unless g == 1 x % mod end |
.next_prime(n) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/obfuskey/math.rb', line 59 def next_prime(n) if n.bit_length > 512 raise MaximumValueError, "For integers larger than 512-bit, a more advanced prime generator is required." end return 2 if n < 2 return [3, 5, 5][n - 2] if n < 5 gap = [ 1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2 ] n += 1 + (n & 1) n += gap[n % 30] if (n % 3).zero? || (n % 5).zero? n += gap[n % 30] until prime?(n) n end |
.prime?(n) ⇒ Boolean
50 51 52 53 54 55 56 57 |
# File 'lib/obfuskey/math.rb', line 50 def prime?(n) return true if n == 2 return false if n < 2 || n.even? return [3, 5, 7, 11, 13, 17].include?(n) if n.gcd(510_510) > 1 return trial_division(n) if n < 2_000_000 small_strong_pseudoprime(n) end |
.small_strong_pseudoprime(n) ⇒ Object
46 47 48 |
# File 'lib/obfuskey/math.rb', line 46 def small_strong_pseudoprime(n) [2, 13, 23, 1_662_803].all? { |base| strong_pseudoprime(n, base) } end |
.strong_pseudoprime(n, base = 2) ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/obfuskey/math.rb', line 29 def strong_pseudoprime(n, base = 2) return false if n.even? return false if n == 1 s, d = factor(n) x = base.pow(d, n) return true if x == 1 || x == n - 1 (s - 1).times do x = x.pow(2, n) return true if x == n - 1 return false if x == 1 end false end |
.trial_division(n) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/obfuskey/math.rb', line 15 def trial_division(n) return false if n <= 1 return true if n == 2 return false if n.even? i = 3 limit = Integer.sqrt(n) while i <= limit return false if (n % i).zero? i += 2 end true end |