Class: ECDSA::PrimeField
- Inherits:
-
Object
- Object
- ECDSA::PrimeField
- Defined in:
- lib/ecdsa/prime_field.rb
Overview
Instances of this class represent a field where the elements are non-negative integers less than a prime p.
To add two elements of the field:
“‘ruby sum = field.mod(a + b) “`
To multiply two elements of the field:
“‘ruby product = field.mod(a * b) “`
Instance Attribute Summary collapse
-
#prime ⇒ Integer
readonly
The prime number that the field is based on.
Class Method Summary collapse
-
.factor_out_twos(x) ⇒ Object
This method is NOT part of the public API of the ECDSA gem.
-
.jacobi(n, p) ⇒ Object
This method is NOT part of the public API of the ECDSA gem.
Instance Method Summary collapse
-
#include?(e) ⇒ true or false
Returns true if the given object is an integer and a member of the field.
-
#initialize(prime) ⇒ PrimeField
constructor
A new instance of PrimeField.
-
#inverse(n) ⇒ Integer
Computes the multiplicative inverse of a field element using the [Extended Euclidean Algorithm](en.wikipedia.org/wiki/Extended_Euclidean_algorithm).
-
#mod(n) ⇒ Integer
Calculates the remainder of ‘n` after being divided by the field’s prime.
-
#power(n, m) ⇒ Integer
Computes ‘n` raised to the power `m`.
-
#square(n) ⇒ Integer
Computes ‘n` multiplied by itself.
-
#square_roots(n) ⇒ Array
Finds all possible square roots of the given field element.
Constructor Details
#initialize(prime) ⇒ PrimeField
Returns a new instance of PrimeField.
20 21 22 23 |
# File 'lib/ecdsa/prime_field.rb', line 20 def initialize(prime) raise ArgumentError, "Invalid prime #{prime.inspect}" if !prime.is_a?(Integer) @prime = prime end |
Instance Attribute Details
#prime ⇒ Integer (readonly)
Returns the prime number that the field is based on.
18 19 20 |
# File 'lib/ecdsa/prime_field.rb', line 18 def prime @prime end |
Class Method Details
.factor_out_twos(x) ⇒ Object
This method is NOT part of the public API of the ECDSA gem.
105 106 107 108 109 110 111 112 |
# File 'lib/ecdsa/prime_field.rb', line 105 def self.factor_out_twos(x) e = 0 while x.even? x /= 2 e += 1 end [e, x] end |
.jacobi(n, p) ⇒ Object
This method is NOT part of the public API of the ECDSA gem.
Algorithm algorithm 2.149 from cacr.uwaterloo.ca/hac/
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/ecdsa/prime_field.rb', line 117 def self.jacobi(n, p) raise 'Jacobi symbol is not defined for primes less than 3.' if p < 3 n = n % p return 0 if n == 0 # Step 1 return 1 if n == 1 # Step 2 e, n1 = factor_out_twos n # Step 3 s = (e.even? || [1, 7].include?(p % 8)) ? 1 : -1 # Step 4 s = -s if (p % 4) == 3 && (n1 % 4) == 3 # Step 5 # Step 6 and 7 return s if n1 == 1 s * jacobi(p, n1) end |
Instance Method Details
#include?(e) ⇒ true or false
Returns true if the given object is an integer and a member of the field.
28 29 30 |
# File 'lib/ecdsa/prime_field.rb', line 28 def include?(e) e.is_a?(Integer) && e >= 0 && e < prime end |
#inverse(n) ⇒ Integer
Computes the multiplicative inverse of a field element using the [Extended Euclidean Algorithm](en.wikipedia.org/wiki/Extended_Euclidean_algorithm).
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/ecdsa/prime_field.rb', line 44 def inverse(n) raise ArgumentError, '0 has no multiplicative inverse.' if n.zero? # For every i, we make sure that num * s[i] + prime * t[i] = r[i]. # Eventually r[i] will equal 1 because gcd(num, prime) is always 1. # At that point, s[i] is the multiplicative inverse of num in the field. remainders = [n, prime] s = [1, 0] t = [0, 1] arrays = [remainders, s, t] while remainders.last > 0 quotient = remainders[-2] / remainders[-1] arrays.each do |array| array << array[-2] - quotient * array[-1] end end raise 'Inversion bug: remainder is not 1.' if remainders[-2] != 1 mod s[-2] end |
#mod(n) ⇒ Integer
Calculates the remainder of ‘n` after being divided by the field’s prime.
35 36 37 |
# File 'lib/ecdsa/prime_field.rb', line 35 def mod(n) n % prime end |
#power(n, m) ⇒ Integer
Computes ‘n` raised to the power `m`. This algorithm uses the same idea as ECDSA::Point#multiply_by_scalar.
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/ecdsa/prime_field.rb', line 72 def power(n, m) result = 1 v = n while m > 0 result = mod result * v if m.odd? v = square v m >>= 1 end result end |
#square(n) ⇒ Integer
Computes ‘n` multiplied by itself.
86 87 88 |
# File 'lib/ecdsa/prime_field.rb', line 86 def square(n) mod n * n end |
#square_roots(n) ⇒ Array
Finds all possible square roots of the given field element.
94 95 96 97 98 99 100 101 102 |
# File 'lib/ecdsa/prime_field.rb', line 94 def square_roots(n) raise ArgumentError, "Not a member of the field: #{n}." if !include?(n) case when prime == 2 then [n] when (prime % 4) == 3 then square_roots_for_p_3_mod_4(n) when (prime % 8) == 5 then square_roots_for_p_5_mod_8(n) else square_roots_default(n) end end |