Class: EllipticCurve::Math
- Inherits:
-
Object
- Object
- EllipticCurve::Math
- Defined in:
- lib/math.rb
Class Method Summary collapse
- ._fromJacobian(p, prime) ⇒ Object
- ._jacobianAdd(p, q, coeff, prime) ⇒ Object
- ._jacobianDouble(p, coeff, prime) ⇒ Object
- ._jacobianMultiply(p, n, order, coeff, prime) ⇒ Object
- ._toJacobian(p) ⇒ Object
- .add(p, q, coeff, prime) ⇒ Object
- .inv(x, n) ⇒ Object
- .modularSquareRoot(value, prime) ⇒ Object
- .multiply(p, n, order, coeff, prime) ⇒ Object
Class Method Details
._fromJacobian(p, prime) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/math.rb', line 70 def self._fromJacobian(p, prime) # Convert point back from Jacobian coordinates # :param p: First Point you want to add # :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Point in default coordinates z = self.inv(p.z, prime) x = (p.x * z ** 2) % prime y = (p.y * z ** 3) % prime return Point.new(x, y, 0) end |
._jacobianAdd(p, q, coeff, prime) ⇒ Object
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'lib/math.rb', line 102 def self._jacobianAdd(p, q, coeff, prime) # Add two points in elliptic curves # :param p: First Point you want to add # :param q: Second Point you want to add # :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p) # :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Point that represents the sum of First and Second Point if p.y == 0 then return q end if q.y == 0 then return p end u1 = (p.x * q.z ** 2) % prime u2 = (q.x * p.z ** 2) % prime s1 = (p.y * q.z ** 3) % prime s2 = (q.y * p.z ** 3) % prime if u1 == u2 if s1 != s2 then return Point.new(0, 0, 1) end return self._jacobianDouble(p, coeff, prime) end h = u2 - u1 r = s2 - s1 h2 = (h * h) % prime h3 = (h * h2) % prime u1h2 = (u1 * h2) % prime nx = (r ** 2 - h3 - 2 * u1h2) % prime ny = (r * (u1h2 - nx) - s1 * h3) % prime nz = (h * p.z * q.z) % prime return Point.new(nx, ny, nz) end |
._jacobianDouble(p, coeff, prime) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/math.rb', line 83 def self._jacobianDouble(p, coeff, prime) # Double a point in elliptic curves # :param p: Point you want to double # :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p) # :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Point that represents the sum of First and Second Point if p.y == 0 then return Point.new(0, 0, 0) end ysq = (p.y ** 2) % prime s = (4 * p.x * ysq) % prime m = (3 * p.x ** 2 + coeff * p.z ** 4) % prime nx = (m ** 2 - 2 * s) % prime ny = (m * (s - nx) - 8 * ysq ** 2) % prime nz = (2 * p.y * p.z) % prime return Point.new(nx, ny, nz) end |
._jacobianMultiply(p, n, order, coeff, prime) ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/math.rb', line 135 def self._jacobianMultiply(p, n, order, coeff, prime) # Multiply point and scalar in elliptic curves # :param p: First Point to mutiply # :param n: Scalar to mutiply # :param N: Order of the elliptic curve # :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Point that represents the sum of First and Second Point if p.y == 0 or n == 0 return Point.new(0, 0, 1) end if n == 1 return p end if n < 0 or n >= order return self._jacobianMultiply(p, n % order, order, coeff, prime) end if (n % 2) == 0 return self._jacobianDouble( self._jacobianMultiply(p, n.div(2), order, coeff, prime), coeff, prime ) end return self._jacobianAdd( self._jacobianDouble(self._jacobianMultiply(p, n.div(2), order, coeff, prime), coeff, prime), p, coeff, prime ) end |
._toJacobian(p) ⇒ Object
62 63 64 65 66 67 68 |
# File 'lib/math.rb', line 62 def self._toJacobian(p) # Convert point to Jacobian coordinates # :param p: First Point you want to add # :return: Point in Jacobian coordinates return Point.new(p.x, p.y, 1) end |
.add(p, q, coeff, prime) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/math.rb', line 24 def self.add(p, q, coeff, prime) # Fast way to add two points in elliptic curves # :param p: First Point you want to add # :param q: Second Point you want to add # :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Point that represents the sum of First and Second Point return self._fromJacobian( self._jacobianAdd(self._toJacobian(p), self._toJacobian(q), coeff, prime), prime ) end |
.inv(x, n) ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/math.rb', line 37 def self.inv(x, n) # Extended Euclidean Algorithm. It's the 'division' in elliptic curves # :param x: Divisor # :param n: Mod for division # :return: Value representing the division if x == 0 then return 0 end lm = 1 hm = 0 low = x % n high = n while low > 1 r = high.div(low) nm = hm - lm * r nw = high - low * r high = low hm = lm low = nw lm = nm end return lm % n end |
.modularSquareRoot(value, prime) ⇒ Object
3 4 5 6 7 8 |
# File 'lib/math.rb', line 3 def self.modularSquareRoot(value, prime) # :param value: Value to calculate the square root # :param prime: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Square root of the value return value.pow((prime + 1).div(4), prime) end |
.multiply(p, n, order, coeff, prime) ⇒ Object
10 11 12 13 14 15 16 17 18 19 20 21 22 |
# File 'lib/math.rb', line 10 def self.multiply(p, n, order, coeff, prime) # Fast way to multiply point and scalar in elliptic curves # :param p: First Point to mutiply # :param n: Scalar to mutiply # :param N: Order of the elliptic curve # :param A: Coefficient of the first-order term of the equation Y^2 = X^3 + A*X + B (mod p) # :param P: Prime number in the module of the equation Y^2 = X^3 + A*X + B (mod p) # :return: Point that represents the sum of First and Second Point return self._fromJacobian( self._jacobianMultiply(self._toJacobian(p), n, order, coeff, prime), prime ) end |