1 // Copyright (c) 2015-2024 The Decred developers
2 // Copyright 2013-2014 The btcsuite developers
3 // Use of this source code is governed by an ISC
4 // license that can be found in the LICENSE file.
5 6 package secp256k1
7 8 import (
9 "encoding/hex"
10 "math/bits"
11 )
12 13 // References:
14 // [SECG]: Recommended Elliptic Curve Domain Parameters
15 // https://www.secg.org/sec2-v2.pdf
16 //
17 // [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
18 //
19 // [BRID]: On Binary Representations of Integers with Digits -1, 0, 1
20 // (Prodinger, Helmut)
21 //
22 // [STWS]: Secure-TWS: Authenticating Node to Multi-user Communication in
23 // Shared Sensor Networks (Oliveira, Leonardo B. et al)
24 25 // All group operations are performed using Jacobian coordinates. For a given
26 // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
27 // where x = x1/z1^2 and y = y1/z1^3.
28 29 // hexToFieldVal converts the passed hex string into a FieldVal and will panic
30 // if there is an error. This is only provided for the hard-coded constants so
31 // errors in the source code can be detected. It will only (and must only) be
32 // called with hard-coded values.
33 func hexToFieldVal(s string) *FieldVal {
34 b, err := hex.DecodeString(s)
35 if err != nil {
36 panic("invalid hex in source file: " + s)
37 }
38 var f FieldVal
39 if overflow := f.SetByteSlice(b); overflow {
40 panic("hex in source file overflows mod P: " + s)
41 }
42 return &f
43 }
44 45 // hexToModNScalar converts the passed hex string into a ModNScalar and will
46 // panic if there is an error. This is only provided for the hard-coded
47 // constants so errors in the source code can be detected. It will only (and
48 // must only) be called with hard-coded values.
49 func hexToModNScalar(s string) *ModNScalar {
50 var isNegative bool
51 if len(s) > 0 && s[0] == '-' {
52 isNegative = true
53 s = s[1:]
54 }
55 if len(s)%2 != 0 {
56 s = "0" + s
57 }
58 b, err := hex.DecodeString(s)
59 if err != nil {
60 panic("invalid hex in source file: " + s)
61 }
62 var scalar ModNScalar
63 if overflow := scalar.SetByteSlice(b); overflow {
64 panic("hex in source file overflows mod N scalar: " + s)
65 }
66 if isNegative {
67 scalar.Negate()
68 }
69 return &scalar
70 }
71 72 var (
73 // The following constants are used to accelerate scalar point
74 // multiplication through the use of the endomorphism:
75 //
76 // φ(Q) ⟼ λ*Q = (β*Q.x mod p, Q.y)
77 //
78 // See the code in the deriveEndomorphismParams function in genprecomps.go
79 // for details on their derivation.
80 //
81 // Additionally, see the scalar multiplication function in this file for
82 // details on how they are used.
83 endoNegLambda = hexToModNScalar("-5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72")
84 endoBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee")
85 endoNegB1 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c3")
86 endoNegB2 = hexToModNScalar("-3086d221a7d46bcde86c90e49284eb15")
87 endoZ1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f")
88 endoZ2 = hexToModNScalar("e4437ed6010e88286f547fa90abfe4c4221208ac9df506c6")
89 90 // Alternatively, the following parameters are valid as well, however,
91 // benchmarks show them to be about 2% slower in practice.
92 // endoNegLambda = hexToModNScalar("-ac9c52b33fa3cf1f5ad9e3fd77ed9ba4a880b9fc8ec739c2e0cfc810b51283ce")
93 // endoBeta = hexToFieldVal("851695d49a83f8ef919bb86153cbcb16630fb68aed0a766a3ec693d68e6afa40")
94 // endoNegB1 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb15")
95 // endoNegB2 = hexToModNScalar("-114ca50f7a8e2f3f657c1108d9d44cfd8")
96 // endoZ1 = hexToModNScalar("114ca50f7a8e2f3f657c1108d9d44cfd95fbc92c10fddd145")
97 // endoZ2 = hexToModNScalar("3086d221a7d46bcde86c90e49284eb153daa8a1471e8ca7f")
98 )
99 100 // JacobianPoint is an element of the group formed by the secp256k1 curve in
101 // Jacobian projective coordinates and thus represents a point on the curve.
102 type JacobianPoint struct {
103 // The X coordinate in Jacobian projective coordinates. The affine point is
104 // X/z^2.
105 X FieldVal
106 107 // The Y coordinate in Jacobian projective coordinates. The affine point is
108 // Y/z^3.
109 Y FieldVal
110 111 // The Z coordinate in Jacobian projective coordinates.
112 Z FieldVal
113 }
114 115 // MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z
116 // coordinates.
117 func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint {
118 var p JacobianPoint
119 p.X.Set(x)
120 p.Y.Set(y)
121 p.Z.Set(z)
122 return p
123 }
124 125 // Set sets the Jacobian point to the provided point.
126 func (p *JacobianPoint) Set(other *JacobianPoint) {
127 p.X.Set(&other.X)
128 p.Y.Set(&other.Y)
129 p.Z.Set(&other.Z)
130 }
131 132 // ToAffine reduces the Z value of the existing point to 1 effectively
133 // making it an affine coordinate in constant time. The point will be
134 // normalized.
135 func (p *JacobianPoint) ToAffine() {
136 // Inversions are expensive and both point addition and point doubling
137 // are faster when working with points that have a z value of one. So,
138 // if the point needs to be converted to affine, go ahead and normalize
139 // the point itself at the same time as the calculation is the same.
140 var zInv, tempZ FieldVal
141 zInv.Set(&p.Z).Inverse() // zInv = Z^-1
142 tempZ.SquareVal(&zInv) // tempZ = Z^-2
143 p.X.Mul(&tempZ) // X = X/Z^2 (mag: 1)
144 p.Y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1)
145 p.Z.SetInt(1) // Z = 1 (mag: 1)
146 147 // Normalize the x and y values.
148 p.X.Normalize()
149 p.Y.Normalize()
150 }
151 152 // EquivalentNonConst returns whether or not two Jacobian points represent the
153 // same affine point in *non-constant* time.
154 func (p *JacobianPoint) EquivalentNonConst(other *JacobianPoint) bool {
155 // Since the point at infinity is the identity element for the group, note
156 // that P = P + ∞ trivially implies that P - P = ∞.
157 //
158 // Use that fact to determine if the points represent the same affine point.
159 var result JacobianPoint
160 result.Set(p)
161 result.Y.Normalize().Negate(1).Normalize()
162 AddNonConst(&result, other, &result)
163 return (result.X.IsZero() && result.Y.IsZero()) || result.Z.IsZero()
164 }
165 166 // addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have
167 // z values of 1 and stores the result in the provided result param. That is to
168 // say result = p1 + p2. It performs faster addition than the generic add
169 // routine since less arithmetic is needed due to the ability to avoid the z
170 // value multiplications.
171 //
172 // NOTE: The points must be normalized for this function to return the correct
173 // result. The resulting point will be normalized.
174 func addZ1AndZ2EqualsOne(p1, p2, result *JacobianPoint) {
175 // To compute the point addition efficiently, this implementation splits
176 // the equation into intermediate elements which are used to minimize
177 // the number of field multiplications using the method shown at:
178 // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
179 //
180 // In particular it performs the calculations using the following:
181 // H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I
182 // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H
183 //
184 // This results in a cost of 4 field multiplications, 2 field squarings,
185 // 6 field additions, and 5 integer multiplications.
186 x1, y1 := &p1.X, &p1.Y
187 x2, y2 := &p2.X, &p2.Y
188 x3, y3, z3 := &result.X, &result.Y, &result.Z
189 190 // When the x coordinates are the same for two points on the curve, the
191 // y coordinates either must be the same, in which case it is point
192 // doubling, or they are opposite and the result is the point at
193 // infinity per the group law for elliptic curve cryptography.
194 if x1.Equals(x2) {
195 if y1.Equals(y2) {
196 // Since x1 == x2 and y1 == y2, point doubling must be
197 // done, otherwise the addition would end up dividing
198 // by zero.
199 DoubleNonConst(p1, result)
200 return
201 }
202 203 // Since x1 == x2 and y1 == -y2, the sum is the point at
204 // infinity per the group law.
205 x3.SetInt(0)
206 y3.SetInt(0)
207 z3.SetInt(0)
208 return
209 }
210 211 // Calculate X3, Y3, and Z3 according to the intermediate elements
212 // breakdown above.
213 var h, i, j, r, v FieldVal
214 var negJ, neg2V, negX3 FieldVal
215 h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3)
216 i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4)
217 j.Mul2(&h, &i) // J = H*I (mag: 1)
218 r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6)
219 v.Mul2(x1, &i) // V = X1*I (mag: 1)
220 negJ.Set(&j).Negate(1) // negJ = -J (mag: 2)
221 neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3)
222 x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6)
223 negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7)
224 j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3)
225 y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4)
226 z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6)
227 228 // Normalize the resulting field values as needed.
229 x3.Normalize()
230 y3.Normalize()
231 z3.Normalize()
232 }
233 234 // addZ1EqualsZ2 adds two Jacobian points that are already known to have the
235 // same z value and stores the result in the provided result param. That is to
236 // say result = p1 + p2. It performs faster addition than the generic add
237 // routine since less arithmetic is needed due to the known equivalence.
238 //
239 // NOTE: The points must be normalized for this function to return the correct
240 // result. The resulting point will be normalized.
241 func addZ1EqualsZ2(p1, p2, result *JacobianPoint) {
242 // To compute the point addition efficiently, this implementation splits
243 // the equation into intermediate elements which are used to minimize
244 // the number of field multiplications using a slightly modified version
245 // of the method shown at:
246 // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-zadd-2007-m
247 //
248 // In particular it performs the calculations using the following:
249 // A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B
250 // X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A
251 //
252 // This results in a cost of 5 field multiplications, 2 field squarings,
253 // 9 field additions, and 0 integer multiplications.
254 x1, y1, z1 := &p1.X, &p1.Y, &p1.Z
255 x2, y2 := &p2.X, &p2.Y
256 x3, y3, z3 := &result.X, &result.Y, &result.Z
257 258 // When the x coordinates are the same for two points on the curve, the
259 // y coordinates either must be the same, in which case it is point
260 // doubling, or they are opposite and the result is the point at
261 // infinity per the group law for elliptic curve cryptography.
262 if x1.Equals(x2) {
263 if y1.Equals(y2) {
264 // Since x1 == x2 and y1 == y2, point doubling must be
265 // done, otherwise the addition would end up dividing
266 // by zero.
267 DoubleNonConst(p1, result)
268 return
269 }
270 271 // Since x1 == x2 and y1 == -y2, the sum is the point at
272 // infinity per the group law.
273 x3.SetInt(0)
274 y3.SetInt(0)
275 z3.SetInt(0)
276 return
277 }
278 279 // Calculate X3, Y3, and Z3 according to the intermediate elements
280 // breakdown above.
281 var a, b, c, d, e, f FieldVal
282 var negX1, negY1, negE, negX3 FieldVal
283 negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
284 negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
285 a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3)
286 b.SquareVal(&a) // B = A^2 (mag: 1)
287 c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3)
288 d.SquareVal(&c) // D = C^2 (mag: 1)
289 e.Mul2(x1, &b) // E = X1*B (mag: 1)
290 negE.Set(&e).Negate(1) // negE = -E (mag: 2)
291 f.Mul2(x2, &b) // F = X2*B (mag: 1)
292 x3.Add2(&e, &f).Negate(2).Add(&d) // X3 = D-E-F (mag: 4)
293 negX3.Set(x3).Negate(4) // negX3 = -X3 (mag: 5)
294 y3.Set(y1).Mul(f.Add(&negE)).Negate(1) // Y3 = -(Y1*(F-E)) (mag: 2)
295 y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 3)
296 z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1)
297 298 // Normalize the resulting field values as needed.
299 x3.Normalize()
300 y3.Normalize()
301 z3.Normalize()
302 }
303 304 // addZ2EqualsOne adds two Jacobian points when the second point is already
305 // known to have a z value of 1 (and the z value for the first point is not 1)
306 // and stores the result in the provided result param. That is to say result =
307 // p1 + p2. It performs faster addition than the generic add routine since
308 // less arithmetic is needed due to the ability to avoid multiplications by the
309 // second point's z value.
310 //
311 // NOTE: The points must be normalized for this function to return the correct
312 // result. The resulting point will be normalized.
313 func addZ2EqualsOne(p1, p2, result *JacobianPoint) {
314 // To compute the point addition efficiently, this implementation splits
315 // the equation into intermediate elements which are used to minimize
316 // the number of field multiplications using the method shown at:
317 // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
318 //
319 // In particular it performs the calculations using the following:
320 // Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2,
321 // I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I
322 // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH
323 //
324 // This results in a cost of 7 field multiplications, 4 field squarings,
325 // 9 field additions, and 4 integer multiplications.
326 x1, y1, z1 := &p1.X, &p1.Y, &p1.Z
327 x2, y2 := &p2.X, &p2.Y
328 x3, y3, z3 := &result.X, &result.Y, &result.Z
329 330 // When the x coordinates are the same for two points on the curve, the
331 // y coordinates either must be the same, in which case it is point
332 // doubling, or they are opposite and the result is the point at
333 // infinity per the group law for elliptic curve cryptography. Since
334 // any number of Jacobian coordinates can represent the same affine
335 // point, the x and y values need to be converted to like terms. Due to
336 // the assumption made for this function that the second point has a z
337 // value of 1 (z2=1), the first point is already "converted".
338 var z1z1, u2, s2 FieldVal
339 z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
340 u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
341 s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
342 if x1.Equals(&u2) {
343 if y1.Equals(&s2) {
344 // Since x1 == x2 and y1 == y2, point doubling must be
345 // done, otherwise the addition would end up dividing
346 // by zero.
347 DoubleNonConst(p1, result)
348 return
349 }
350 351 // Since x1 == x2 and y1 == -y2, the sum is the point at
352 // infinity per the group law.
353 x3.SetInt(0)
354 y3.SetInt(0)
355 z3.SetInt(0)
356 return
357 }
358 359 // Calculate X3, Y3, and Z3 according to the intermediate elements
360 // breakdown above.
361 var h, hh, i, j, r, rr, v FieldVal
362 var negX1, negY1, negX3 FieldVal
363 negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
364 h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3)
365 hh.SquareVal(&h) // HH = H^2 (mag: 1)
366 i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4)
367 j.Mul2(&h, &i) // J = H*I (mag: 1)
368 negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
369 r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6)
370 rr.SquareVal(&r) // rr = r^2 (mag: 1)
371 v.Mul2(x1, &i) // V = X1*I (mag: 1)
372 x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
373 x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
374 negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
375 y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3)
376 y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
377 z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1)
378 z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4)
379 380 // Normalize the resulting field values as needed.
381 x3.Normalize()
382 y3.Normalize()
383 z3.Normalize()
384 }
385 386 // addGeneric adds two Jacobian points without any assumptions about the z
387 // values of the two points and stores the result in the provided result param.
388 // That is to say result = p1 + p2. It is the slowest of the add routines due
389 // to requiring the most arithmetic.
390 //
391 // NOTE: The points must be normalized for this function to return the correct
392 // result. The resulting point will be normalized.
393 func addGeneric(p1, p2, result *JacobianPoint) {
394 // To compute the point addition efficiently, this implementation splits
395 // the equation into intermediate elements which are used to minimize
396 // the number of field multiplications using the method shown at:
397 // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
398 //
399 // In particular it performs the calculations using the following:
400 // Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2
401 // S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1)
402 // V = U1*I
403 // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H
404 //
405 // This results in a cost of 11 field multiplications, 5 field squarings,
406 // 9 field additions, and 4 integer multiplications.
407 x1, y1, z1 := &p1.X, &p1.Y, &p1.Z
408 x2, y2, z2 := &p2.X, &p2.Y, &p2.Z
409 x3, y3, z3 := &result.X, &result.Y, &result.Z
410 411 // When the x coordinates are the same for two points on the curve, the
412 // y coordinates either must be the same, in which case it is point
413 // doubling, or they are opposite and the result is the point at
414 // infinity. Since any number of Jacobian coordinates can represent the
415 // same affine point, the x and y values need to be converted to like
416 // terms.
417 var z1z1, z2z2, u1, u2, s1, s2 FieldVal
418 z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
419 z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1)
420 u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1)
421 u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
422 s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1)
423 s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
424 if u1.Equals(&u2) {
425 if s1.Equals(&s2) {
426 // Since x1 == x2 and y1 == y2, point doubling must be
427 // done, otherwise the addition would end up dividing
428 // by zero.
429 DoubleNonConst(p1, result)
430 return
431 }
432 433 // Since x1 == x2 and y1 == -y2, the sum is the point at
434 // infinity per the group law.
435 x3.SetInt(0)
436 y3.SetInt(0)
437 z3.SetInt(0)
438 return
439 }
440 441 // Calculate X3, Y3, and Z3 according to the intermediate elements
442 // breakdown above.
443 var h, i, j, r, rr, v FieldVal
444 var negU1, negS1, negX3 FieldVal
445 negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2)
446 h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3)
447 i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 1)
448 j.Mul2(&h, &i) // J = H*I (mag: 1)
449 negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2)
450 r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6)
451 rr.SquareVal(&r) // rr = r^2 (mag: 1)
452 v.Mul2(&u1, &i) // V = U1*I (mag: 1)
453 x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
454 x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
455 negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
456 y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3)
457 y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
458 z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1)
459 z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4)
460 z3.Mul(&h) // Z3 = Z3*H (mag: 1)
461 462 // Normalize the resulting field values as needed.
463 x3.Normalize()
464 y3.Normalize()
465 z3.Normalize()
466 }
467 468 // AddNonConst adds the passed Jacobian points together and stores the result in
469 // the provided result param in *non-constant* time.
470 //
471 // NOTE: The points must be normalized for this function to return the correct
472 // result. The resulting point will be normalized.
473 func AddNonConst(p1, p2, result *JacobianPoint) {
474 // The point at infinity is the identity according to the group law for
475 // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
476 if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() {
477 result.Set(p2)
478 return
479 }
480 if (p2.X.IsZero() && p2.Y.IsZero()) || p2.Z.IsZero() {
481 result.Set(p1)
482 return
483 }
484 485 // Faster point addition can be achieved when certain assumptions are
486 // met. For example, when both points have the same z value, arithmetic
487 // on the z values can be avoided. This section thus checks for these
488 // conditions and calls an appropriate add function which is accelerated
489 // by using those assumptions.
490 isZ1One := p1.Z.IsOne()
491 isZ2One := p2.Z.IsOne()
492 switch {
493 case isZ1One && isZ2One:
494 addZ1AndZ2EqualsOne(p1, p2, result)
495 return
496 case p1.Z.Equals(&p2.Z):
497 addZ1EqualsZ2(p1, p2, result)
498 return
499 case isZ2One:
500 addZ2EqualsOne(p1, p2, result)
501 return
502 }
503 504 // None of the above assumptions are true, so fall back to generic
505 // point addition.
506 addGeneric(p1, p2, result)
507 }
508 509 // doubleZ1EqualsOne performs point doubling on the passed Jacobian point when
510 // the point is already known to have a z value of 1 and stores the result in
511 // the provided result param. That is to say result = 2*p. It performs faster
512 // point doubling than the generic routine since less arithmetic is needed due
513 // to the ability to avoid multiplication by the z value.
514 //
515 // NOTE: The resulting point will be normalized.
516 func doubleZ1EqualsOne(p, result *JacobianPoint) {
517 // This function uses the assumptions that z1 is 1, thus the point
518 // doubling formulas reduce to:
519 //
520 // X3 = (3*X1^2)^2 - 8*X1*Y1^2
521 // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
522 // Z3 = 2*Y1
523 //
524 // To compute the above efficiently, this implementation splits the
525 // equation into intermediate elements which are used to minimize the
526 // number of field multiplications in favor of field squarings which
527 // are roughly 35% faster than field multiplications with the current
528 // implementation at the time this was written.
529 //
530 // This uses a slightly modified version of the method shown at:
531 // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl
532 //
533 // In particular it performs the calculations using the following:
534 // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
535 // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
536 // Z3 = 2*Y1
537 //
538 // This results in a cost of 1 field multiplication, 5 field squarings,
539 // 6 field additions, and 5 integer multiplications.
540 x1, y1 := &p.X, &p.Y
541 x3, y3, z3 := &result.X, &result.Y, &result.Z
542 var a, b, c, d, e, f FieldVal
543 z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2)
544 a.SquareVal(x1) // A = X1^2 (mag: 1)
545 b.SquareVal(y1) // B = Y1^2 (mag: 1)
546 c.SquareVal(&b) // C = B^2 (mag: 1)
547 b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
548 d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
549 d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
550 e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
551 f.SquareVal(&e) // F = E^2 (mag: 1)
552 x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
553 x3.Add(&f) // X3 = F+X3 (mag: 18)
554 f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
555 y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
556 y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
557 558 // Normalize the resulting field values as needed.
559 x3.Normalize()
560 y3.Normalize()
561 z3.Normalize()
562 }
563 564 // doubleGeneric performs point doubling on the passed Jacobian point without
565 // any assumptions about the z value and stores the result in the provided
566 // result param. That is to say result = 2*p. It is the slowest of the point
567 // doubling routines due to requiring the most arithmetic.
568 //
569 // NOTE: The resulting point will be normalized.
570 func doubleGeneric(p, result *JacobianPoint) {
571 // Point doubling formula for Jacobian coordinates for the secp256k1
572 // curve:
573 //
574 // X3 = (3*X1^2)^2 - 8*X1*Y1^2
575 // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
576 // Z3 = 2*Y1*Z1
577 //
578 // To compute the above efficiently, this implementation splits the
579 // equation into intermediate elements which are used to minimize the
580 // number of field multiplications in favor of field squarings which
581 // are roughly 35% faster than field multiplications with the current
582 // implementation at the time this was written.
583 //
584 // This uses a slightly modified version of the method shown at:
585 // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
586 //
587 // In particular it performs the calculations using the following:
588 // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
589 // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
590 // Z3 = 2*Y1*Z1
591 //
592 // This results in a cost of 1 field multiplication, 5 field squarings,
593 // 6 field additions, and 5 integer multiplications.
594 x1, y1, z1 := &p.X, &p.Y, &p.Z
595 x3, y3, z3 := &result.X, &result.Y, &result.Z
596 var a, b, c, d, e, f FieldVal
597 z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2)
598 a.SquareVal(x1) // A = X1^2 (mag: 1)
599 b.SquareVal(y1) // B = Y1^2 (mag: 1)
600 c.SquareVal(&b) // C = B^2 (mag: 1)
601 b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
602 d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
603 d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
604 e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
605 f.SquareVal(&e) // F = E^2 (mag: 1)
606 x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
607 x3.Add(&f) // X3 = F+X3 (mag: 18)
608 f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
609 y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
610 y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
611 612 // Normalize the resulting field values as needed.
613 x3.Normalize()
614 y3.Normalize()
615 z3.Normalize()
616 }
617 618 // DoubleNonConst doubles the passed Jacobian point and stores the result in the
619 // provided result parameter in *non-constant* time.
620 //
621 // NOTE: The point must be normalized for this function to return the correct
622 // result. The resulting point will be normalized.
623 func DoubleNonConst(p, result *JacobianPoint) {
624 // Doubling the point at infinity is still infinity.
625 if p.Y.IsZero() || p.Z.IsZero() {
626 result.X.SetInt(0)
627 result.Y.SetInt(0)
628 result.Z.SetInt(0)
629 return
630 }
631 632 // Slightly faster point doubling can be achieved when the z value is 1
633 // by avoiding the multiplication on the z value. This section calls
634 // a point doubling function which is accelerated by using that
635 // assumption when possible.
636 if p.Z.IsOne() {
637 doubleZ1EqualsOne(p, result)
638 return
639 }
640 641 // Fall back to generic point doubling which works with arbitrary z
642 // values.
643 doubleGeneric(p, result)
644 }
645 646 // mulAdd64 multiplies the two passed base 2^64 digits together, adds the given
647 // value to the result, and returns the 128-bit result via a (hi, lo) tuple
648 // where the upper half of the bits are returned in hi and the lower half in lo.
649 func mulAdd64(digit1, digit2, m uint64) (hi, lo uint64) {
650 // Note the carry on the final add is safe to discard because the maximum
651 // possible value is:
652 // (2^64 - 1)(2^64 - 1) + (2^64 - 1) = 2^128 - 2^64
653 // and:
654 // 2^128 - 2^64 < 2^128.
655 var c uint64
656 hi, lo = bits.Mul64(digit1, digit2)
657 lo, c = bits.Add64(lo, m, 0)
658 hi, _ = bits.Add64(hi, 0, c)
659 return hi, lo
660 }
661 662 // mulAdd64Carry multiplies the two passed base 2^64 digits together, adds both
663 // the given value and carry to the result, and returns the 128-bit result via a
664 // (hi, lo) tuple where the upper half of the bits are returned in hi and the
665 // lower half in lo.
666 func mulAdd64Carry(digit1, digit2, m, c uint64) (hi, lo uint64) {
667 // Note the carry on the high order add is safe to discard because the
668 // maximum possible value is:
669 // (2^64 - 1)(2^64 - 1) + 2*(2^64 - 1) = 2^128 - 1
670 // and:
671 // 2^128 - 1 < 2^128.
672 var c2 uint64
673 hi, lo = mulAdd64(digit1, digit2, m)
674 lo, c2 = bits.Add64(lo, c, 0)
675 hi, _ = bits.Add64(hi, 0, c2)
676 return hi, lo
677 }
678 679 // mul512Rsh320Round computes the full 512-bit product of the two given scalars,
680 // right shifts the result by 320 bits, rounds to the nearest integer, and
681 // returns the result in constant time.
682 //
683 // Note that despite the inputs and output being mod n scalars, the 512-bit
684 // product is NOT reduced mod N prior to the right shift. This is intentional
685 // because it is used for replacing division with multiplication and thus the
686 // intermediate results must be done via a field extension to a larger field.
687 func mul512Rsh320Round(n1, n2 *ModNScalar) ModNScalar {
688 // Convert n1 and n2 to base 2^64 digits.
689 n1Digit0 := uint64(n1.n[0]) | uint64(n1.n[1])<<32
690 n1Digit1 := uint64(n1.n[2]) | uint64(n1.n[3])<<32
691 n1Digit2 := uint64(n1.n[4]) | uint64(n1.n[5])<<32
692 n1Digit3 := uint64(n1.n[6]) | uint64(n1.n[7])<<32
693 n2Digit0 := uint64(n2.n[0]) | uint64(n2.n[1])<<32
694 n2Digit1 := uint64(n2.n[2]) | uint64(n2.n[3])<<32
695 n2Digit2 := uint64(n2.n[4]) | uint64(n2.n[5])<<32
696 n2Digit3 := uint64(n2.n[6]) | uint64(n2.n[7])<<32
697 698 // Compute the full 512-bit product n1*n2.
699 var r0, r1, r2, r3, r4, r5, r6, r7, c uint64
700 701 // Terms resulting from the product of the first digit of the second number
702 // by all digits of the first number.
703 //
704 // Note that r0 is ignored because it is not needed to compute the higher
705 // terms and it is shifted out below anyway.
706 c, _ = bits.Mul64(n2Digit0, n1Digit0)
707 c, r1 = mulAdd64(n2Digit0, n1Digit1, c)
708 c, r2 = mulAdd64(n2Digit0, n1Digit2, c)
709 r4, r3 = mulAdd64(n2Digit0, n1Digit3, c)
710 711 // Terms resulting from the product of the second digit of the second number
712 // by all digits of the first number.
713 //
714 // Note that r1 is ignored because it is no longer needed to compute the
715 // higher terms and it is shifted out below anyway.
716 c, _ = mulAdd64(n2Digit1, n1Digit0, r1)
717 c, r2 = mulAdd64Carry(n2Digit1, n1Digit1, r2, c)
718 c, r3 = mulAdd64Carry(n2Digit1, n1Digit2, r3, c)
719 r5, r4 = mulAdd64Carry(n2Digit1, n1Digit3, r4, c)
720 721 // Terms resulting from the product of the third digit of the second number
722 // by all digits of the first number.
723 //
724 // Note that r2 is ignored because it is no longer needed to compute the
725 // higher terms and it is shifted out below anyway.
726 c, _ = mulAdd64(n2Digit2, n1Digit0, r2)
727 c, r3 = mulAdd64Carry(n2Digit2, n1Digit1, r3, c)
728 c, r4 = mulAdd64Carry(n2Digit2, n1Digit2, r4, c)
729 r6, r5 = mulAdd64Carry(n2Digit2, n1Digit3, r5, c)
730 731 // Terms resulting from the product of the fourth digit of the second number
732 // by all digits of the first number.
733 //
734 // Note that r3 is ignored because it is no longer needed to compute the
735 // higher terms and it is shifted out below anyway.
736 c, _ = mulAdd64(n2Digit3, n1Digit0, r3)
737 c, r4 = mulAdd64Carry(n2Digit3, n1Digit1, r4, c)
738 c, r5 = mulAdd64Carry(n2Digit3, n1Digit2, r5, c)
739 r7, r6 = mulAdd64Carry(n2Digit3, n1Digit3, r6, c)
740 741 // At this point the upper 256 bits of the full 512-bit product n1*n2 are in
742 // r4..r7 (recall the low order results were discarded as noted above).
743 //
744 // Right shift the result 320 bits. Note that the MSB of r4 determines
745 // whether or not to round because it is the final bit that is shifted out.
746 //
747 // Also, notice that r3..r7 would also ordinarily be set to 0 as well for
748 // the full shift, but that is skipped since they are no longer used as
749 // their values are known to be zero.
750 roundBit := r4 >> 63
751 r2, r1, r0 = r7, r6, r5
752 753 // Conditionally add 1 depending on the round bit in constant time.
754 r0, c = bits.Add64(r0, roundBit, 0)
755 r1, c = bits.Add64(r1, 0, c)
756 r2, r3 = bits.Add64(r2, 0, c)
757 758 // Finally, convert the result to a mod n scalar.
759 //
760 // No modular reduction is needed because the result is guaranteed to be
761 // less than the group order given the group order is > 2^255 and the
762 // maximum possible value of the result is 2^192.
763 var result ModNScalar
764 result.n[0] = uint32(r0)
765 result.n[1] = uint32(r0 >> 32)
766 result.n[2] = uint32(r1)
767 result.n[3] = uint32(r1 >> 32)
768 result.n[4] = uint32(r2)
769 result.n[5] = uint32(r2 >> 32)
770 result.n[6] = uint32(r3)
771 result.n[7] = uint32(r3 >> 32)
772 return result
773 }
774 775 // splitK returns two scalars (k1 and k2) that are a balanced length-two
776 // representation of the provided scalar such that k ≡ k1 + k2*λ (mod N), where
777 // N is the secp256k1 group order.
778 func splitK(k *ModNScalar) (ModNScalar, ModNScalar) {
779 // The ultimate goal is to decompose k into two scalars that are around
780 // half the bit length of k such that the following equation is satisfied:
781 //
782 // k1 + k2*λ ≡ k (mod n)
783 //
784 // The strategy used here is based on algorithm 3.74 from [GECC] with a few
785 // modifications to make use of the more efficient mod n scalar type, avoid
786 // some costly long divisions, and minimize the number of calculations.
787 //
788 // Start by defining a function that takes a vector v = <a,b> ∈ ℤ⨯ℤ:
789 //
790 // f(v) = a + bλ (mod n)
791 //
792 // Then, find two vectors, v1 = <a1,b1>, and v2 = <a2,b2> in ℤ⨯ℤ such that:
793 // 1) v1 and v2 are linearly independent
794 // 2) f(v1) = f(v2) = 0
795 // 3) v1 and v2 have small Euclidean norm
796 //
797 // The vectors that satisfy these properties are found via the Euclidean
798 // algorithm and are precomputed since both n and λ are fixed values for the
799 // secp256k1 curve. See genprecomps.go for derivation details.
800 //
801 // Next, consider k as a vector <k, 0> in ℚ⨯ℚ and by linear algebra write:
802 //
803 // <k, 0> = g1*v1 + g2*v2, where g1, g2 ∈ ℚ
804 //
805 // Note that, per above, the components of vector v1 are a1 and b1 while the
806 // components of vector v2 are a2 and b2. Given the vectors v1 and v2 were
807 // generated such that a1*b2 - a2*b1 = n, solving the equation for g1 and g2
808 // yields:
809 //
810 // g1 = b2*k / n
811 // g2 = -b1*k / n
812 //
813 // Observe:
814 // <k, 0> = g1*v1 + g2*v2
815 // = (b2*k/n)*<a1,b1> + (-b1*k/n)*<a2,b2> | substitute
816 // = <a1*b2*k/n, b1*b2*k/n> + <-a2*b1*k/n, -b2*b1*k/n> | scalar mul
817 // = <a1*b2*k/n - a2*b1*k/n, b1*b2*k/n - b2*b1*k/n> | vector add
818 // = <[a1*b2*k - a2*b1*k]/n, 0> | simplify
819 // = <k*[a1*b2 - a2*b1]/n, 0> | factor out k
820 // = <k*n/n, 0> | substitute
821 // = <k, 0> | simplify
822 //
823 // Now, consider an integer-valued vector v:
824 //
825 // v = c1*v1 + c2*v2, where c1, c2 ∈ ℤ (mod n)
826 //
827 // Since vectors v1 and v2 are linearly independent and were generated such
828 // that f(v1) = f(v2) = 0, all possible scalars c1 and c2 also produce a
829 // vector v such that f(v) = 0.
830 //
831 // In other words, c1 and c2 can be any integers and the resulting
832 // decomposition will still satisfy the required equation. However, since
833 // the goal is to produce a balanced decomposition that provides a
834 // performance advantage by minimizing max(k1, k2), c1 and c2 need to be
835 // integers close to g1 and g2, respectively, so the resulting vector v is
836 // an integer-valued vector that is close to <k, 0>.
837 //
838 // Finally, consider the vector u:
839 //
840 // u = <k, 0> - v
841 //
842 // It follows that f(u) = k and thus the two components of vector u satisfy
843 // the required equation:
844 //
845 // k1 + k2*λ ≡ k (mod n)
846 //
847 // Choosing c1 and c2:
848 // -------------------
849 //
850 // As mentioned above, c1 and c2 need to be integers close to g1 and g2,
851 // respectively. The algorithm in [GECC] chooses the following values:
852 //
853 // c1 = round(g1) = round(b2*k / n)
854 // c2 = round(g2) = round(-b1*k / n)
855 //
856 // However, as section 3.4.2 of [STWS] notes, the aforementioned approach
857 // requires costly long divisions that can be avoided by precomputing
858 // rounded estimates as follows:
859 //
860 // t = bitlen(n) + 1
861 // z1 = round(2^t * b2 / n)
862 // z2 = round(2^t * -b1 / n)
863 //
864 // Then, use those precomputed estimates to perform a multiplication by k
865 // along with a floored division by 2^t, which is a simple right shift by t:
866 //
867 // c1 = floor(k * z1 / 2^t) = (k * z1) >> t
868 // c2 = floor(k * z2 / 2^t) = (k * z2) >> t
869 //
870 // Finally, round up if last bit discarded in the right shift by t is set by
871 // adding 1.
872 //
873 // As a further optimization, rather than setting t = bitlen(n) + 1 = 257 as
874 // stated by [STWS], this implementation uses a higher precision estimate of
875 // t = bitlen(n) + 64 = 320 because it allows simplification of the shifts
876 // in the internal calculations that are done via uint64s and also allows
877 // the use of floor in the precomputations.
878 //
879 // Thus, the calculations this implementation uses are:
880 //
881 // z1 = floor(b2<<320 / n) | precomputed
882 // z2 = floor((-b1)<<320) / n) | precomputed
883 // c1 = ((k * z1) >> 320) + (((k * z1) >> 319) & 1)
884 // c2 = ((k * z2) >> 320) + (((k * z2) >> 319) & 1)
885 //
886 // Putting it all together:
887 // ------------------------
888 //
889 // Calculate the following vectors using the values discussed above:
890 //
891 // v = c1*v1 + c2*v2
892 // u = <k, 0> - v
893 //
894 // The two components of the resulting vector v are:
895 // va = c1*a1 + c2*a2
896 // vb = c1*b1 + c2*b2
897 //
898 // Thus, the two components of the resulting vector u are:
899 // k1 = k - va
900 // k2 = 0 - vb = -vb
901 //
902 // As some final optimizations:
903 //
904 // 1) Note that k1 + k2*λ ≡ k (mod n) means that k1 ≡ k - k2*λ (mod n).
905 // Therefore, the computation of va can be avoided to save two
906 // field multiplications and a field addition.
907 //
908 // 2) Since k1 ≡ k - k2*λ ≡ k + k2*(-λ), an additional field negation is
909 // saved by storing and using the negative version of λ.
910 //
911 // 3) Since k2 ≡ -vb ≡ -(c1*b1 + c2*b2) ≡ c1*(-b1) + c2*(-b2), one more
912 // field negation is saved by storing and using the negative versions of
913 // b1 and b2.
914 //
915 // k2 = c1*(-b1) + c2*(-b2)
916 // k1 = k + k2*(-λ)
917 var k1, k2 ModNScalar
918 c1 := mul512Rsh320Round(k, endoZ1)
919 c2 := mul512Rsh320Round(k, endoZ2)
920 k2.Add2(c1.Mul(endoNegB1), c2.Mul(endoNegB2))
921 k1.Mul2(&k2, endoNegLambda).Add(k)
922 return k1, k2
923 }
924 925 // nafScalar represents a positive integer up to a maximum value of 2^256 - 1
926 // encoded in non-adjacent form.
927 //
928 // NAF is a signed-digit representation where each digit can be +1, 0, or -1.
929 //
930 // In order to efficiently encode that information, this type uses two arrays, a
931 // "positive" array where set bits represent the +1 signed digits and a
932 // "negative" array where set bits represent the -1 signed digits. 0 is
933 // represented by neither array having a bit set in that position.
934 //
935 // The Pos and Neg methods return the aforementioned positive and negative
936 // arrays, respectively.
937 type nafScalar struct {
938 // pos houses the positive portion of the representation. An additional
939 // byte is required for the positive portion because the NAF encoding can be
940 // up to 1 bit longer than the normal binary encoding of the value.
941 //
942 // neg houses the negative portion of the representation. Even though the
943 // additional byte is not required for the negative portion, since it can
944 // never exceed the length of the normal binary encoding of the value,
945 // keeping the same length for positive and negative portions simplifies
946 // working with the representation and allows extra conditional branches to
947 // be avoided.
948 //
949 // start and end specify the starting and ending index to use within the pos
950 // and neg arrays, respectively. This allows fixed size arrays to be used
951 // versus needing to dynamically allocate space on the heap.
952 //
953 // NOTE: The fields are defined in the order that they are to minimize the
954 // padding on 32-bit and 64-bit platforms.
955 pos [33]byte
956 start, end uint8
957 neg [33]byte
958 }
959 960 // Pos returns the bytes of the encoded value with bits set in the positions
961 // that represent a signed digit of +1.
962 func (s *nafScalar) Pos() []byte {
963 return s.pos[s.start:s.end]
964 }
965 966 // Neg returns the bytes of the encoded value with bits set in the positions
967 // that represent a signed digit of -1.
968 func (s *nafScalar) Neg() []byte {
969 return s.neg[s.start:s.end]
970 }
971 972 // naf takes a positive integer up to a maximum value of 2^256 - 1 and returns
973 // its non-adjacent form (NAF), which is a unique signed-digit representation
974 // such that no two consecutive digits are nonzero. See the documentation for
975 // the returned type for details on how the representation is encoded
976 // efficiently and how to interpret it
977 //
978 // NAF is useful in that it has the fewest nonzero digits of any signed digit
979 // representation, only 1/3rd of its digits are nonzero on average, and at least
980 // half of the digits will be 0.
981 //
982 // The aforementioned properties are particularly beneficial for optimizing
983 // elliptic curve point multiplication because they effectively minimize the
984 // number of required point additions in exchange for needing to perform a mix
985 // of fewer point additions and subtractions and possibly one additional point
986 // doubling. This is an excellent tradeoff because subtraction of points has
987 // the same computational complexity as addition of points and point doubling is
988 // faster than both.
989 func naf(k []byte) nafScalar {
990 // Strip leading zero bytes.
991 for len(k) > 0 && k[0] == 0x00 {
992 k = k[1:]
993 }
994 995 // The non-adjacent form (NAF) of a positive integer k is an expression
996 // k = ∑_(i=0, l-1) k_i * 2^i where k_i ∈ {0,±1}, k_(l-1) != 0, and no two
997 // consecutive digits k_i are nonzero.
998 //
999 // The traditional method of computing the NAF of a positive integer is
1000 // given by algorithm 3.30 in [GECC]. It consists of repeatedly dividing k
1001 // by 2 and choosing the remainder so that the quotient (k−r)/2 is even
1002 // which ensures the next NAF digit is 0. This requires log_2(k) steps.
1003 //
1004 // However, in [BRID], Prodinger notes that a closed form expression for the
1005 // NAF representation is the bitwise difference 3k/2 - k/2. This is more
1006 // efficient as it can be computed in O(1) versus the O(log(n)) of the
1007 // traditional approach.
1008 //
1009 // The following code makes use of that formula to compute the NAF more
1010 // efficiently.
1011 //
1012 // To understand the logic here, observe that the only way the NAF has a
1013 // nonzero digit at a given bit is when either 3k/2 or k/2 has a bit set in
1014 // that position, but not both. In other words, the result of a bitwise
1015 // xor. This can be seen simply by considering that when the bits are the
1016 // same, the subtraction is either 0-0 or 1-1, both of which are 0.
1017 //
1018 // Further, observe that the "+1" digits in the result are contributed by
1019 // 3k/2 while the "-1" digits are from k/2. So, they can be determined by
1020 // taking the bitwise and of each respective value with the result of the
1021 // xor which identifies which bits are nonzero.
1022 //
1023 // Using that information, this loops backwards from the least significant
1024 // byte to the most significant byte while performing the aforementioned
1025 // calculations by propagating the potential carry and high order bit from
1026 // the next word during the right shift.
1027 kLen := len(k)
1028 var result nafScalar
1029 var carry uint8
1030 for byteNum := kLen - 1; byteNum >= 0; byteNum-- {
1031 // Calculate k/2. Notice the carry from the previous word is added and
1032 // the low order bit from the next word is shifted in accordingly.
1033 kc := uint16(k[byteNum]) + uint16(carry)
1034 var nextWord uint8
1035 if byteNum > 0 {
1036 nextWord = k[byteNum-1]
1037 }
1038 halfK := kc>>1 | uint16(nextWord<<7)
1039 1040 // Calculate 3k/2 and determine the non-zero digits in the result.
1041 threeHalfK := kc + halfK
1042 nonZeroResultDigits := threeHalfK ^ halfK
1043 1044 // Determine the signed digits {0, ±1}.
1045 result.pos[byteNum+1] = uint8(threeHalfK & nonZeroResultDigits)
1046 result.neg[byteNum+1] = uint8(halfK & nonZeroResultDigits)
1047 1048 // Propagate the potential carry from the 3k/2 calculation.
1049 carry = uint8(threeHalfK >> 8)
1050 }
1051 result.pos[0] = carry
1052 1053 // Set the starting and ending positions within the fixed size arrays to
1054 // identify the bytes that are actually used. This is important since the
1055 // encoding is big endian and thus trailing zero bytes changes its value.
1056 result.start = 1 - carry
1057 result.end = uint8(kLen + 1)
1058 return result
1059 }
1060 1061 // ScalarMultNonConst multiplies k*P where k is a scalar modulo the curve order
1062 // and P is a point in Jacobian projective coordinates and stores the result in
1063 // the provided Jacobian point.
1064 //
1065 // NOTE: The point must be normalized for this function to return the correct
1066 // result. The resulting point will be normalized.
1067 func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) {
1068 // -------------------------------------------------------------------------
1069 // This makes use of the following efficiently-computable endomorphism to
1070 // accelerate the computation:
1071 //
1072 // φ(P) ⟼ λ*P = (β*P.x mod p, P.y)
1073 //
1074 // In other words, there is a special scalar λ that every point on the
1075 // elliptic curve can be multiplied by that will result in the same point as
1076 // performing a single field multiplication of the point's X coordinate by
1077 // the special value β.
1078 //
1079 // This is useful because scalar point multiplication is significantly more
1080 // expensive than a single field multiplication given the former involves a
1081 // series of point doublings and additions which themselves consist of a
1082 // combination of several field multiplications, squarings, and additions.
1083 //
1084 // So, the idea behind making use of the endomorphism is thus to decompose
1085 // the scalar into two scalars that are each about half the bit length of
1086 // the original scalar such that:
1087 //
1088 // k ≡ k1 + k2*λ (mod n)
1089 //
1090 // This in turn allows the scalar point multiplication to be performed as a
1091 // sum of two smaller half-length multiplications as follows:
1092 //
1093 // k*P = (k1 + k2*λ)*P
1094 // = k1*P + k2*λ*P
1095 // = k1*P + k2*φ(P)
1096 //
1097 // Thus, a speedup is achieved so long as it's faster to decompose the
1098 // scalar, compute φ(P), and perform a simultaneous multiply of the
1099 // half-length point multiplications than it is to compute a full width
1100 // point multiplication.
1101 //
1102 // In practice, benchmarks show the current implementation provides a
1103 // speedup of around 30-35% versus not using the endomorphism.
1104 //
1105 // See section 3.5 in [GECC] for a more rigorous treatment.
1106 // -------------------------------------------------------------------------
1107 1108 // Per above, the main equation here to remember is:
1109 // k*P = k1*P + k2*φ(P)
1110 //
1111 // p1 below is P in the equation while p2 is φ(P) in the equation.
1112 //
1113 // NOTE: φ(x,y) = (β*x,y). The Jacobian z coordinates are the same, so this
1114 // math goes through.
1115 //
1116 // Also, calculate -p1 and -p2 for use in the NAF optimization.
1117 p1, p1Neg := new(JacobianPoint), new(JacobianPoint)
1118 p1.Set(point)
1119 p1Neg.Set(p1)
1120 p1Neg.Y.Negate(1).Normalize()
1121 p2, p2Neg := new(JacobianPoint), new(JacobianPoint)
1122 p2.Set(p1)
1123 p2.X.Mul(endoBeta).Normalize()
1124 p2Neg.Set(p2)
1125 p2Neg.Y.Negate(1).Normalize()
1126 1127 // Decompose k into k1 and k2 such that k = k1 + k2*λ (mod n) where k1 and
1128 // k2 are around half the bit length of k in order to halve the number of EC
1129 // operations.
1130 //
1131 // Notice that this also flips the sign of the scalars and points as needed
1132 // to minimize the bit lengths of the scalars k1 and k2.
1133 //
1134 // This is done because the scalars are operating modulo the group order
1135 // which means that when they would otherwise be a small negative magnitude
1136 // they will instead be a large positive magnitude. Since the goal is for
1137 // the scalars to have a small magnitude to achieve a performance boost, use
1138 // their negation when they are greater than the half order of the group and
1139 // flip the positive and negative values of the corresponding point that
1140 // will be multiplied by to compensate.
1141 //
1142 // In other words, transform the calc when k1 is over the half order to:
1143 // k1*P = -k1*-P
1144 //
1145 // Similarly, transform the calc when k2 is over the half order to:
1146 // k2*φ(P) = -k2*-φ(P)
1147 k1, k2 := splitK(k)
1148 if k1.IsOverHalfOrder() {
1149 k1.Negate()
1150 p1, p1Neg = p1Neg, p1
1151 }
1152 if k2.IsOverHalfOrder() {
1153 k2.Negate()
1154 p2, p2Neg = p2Neg, p2
1155 }
1156 1157 // Convert k1 and k2 into their NAF representations since NAF has a lot more
1158 // zeros overall on average which minimizes the number of required point
1159 // additions in exchange for a mix of fewer point additions and subtractions
1160 // at the cost of one additional point doubling.
1161 //
1162 // This is an excellent tradeoff because subtraction of points has the same
1163 // computational complexity as addition of points and point doubling is
1164 // faster than both.
1165 //
1166 // Concretely, on average, 1/2 of all bits will be non-zero with the normal
1167 // binary representation whereas only 1/3rd of the bits will be non-zero
1168 // with NAF.
1169 //
1170 // The Pos version of the bytes contain the +1s and the Neg versions contain
1171 // the -1s.
1172 k1Bytes, k2Bytes := k1.Bytes(), k2.Bytes()
1173 k1NAF, k2NAF := naf(k1Bytes[:]), naf(k2Bytes[:])
1174 k1PosNAF, k1NegNAF := k1NAF.Pos(), k1NAF.Neg()
1175 k2PosNAF, k2NegNAF := k2NAF.Pos(), k2NAF.Neg()
1176 k1Len, k2Len := len(k1PosNAF), len(k2PosNAF)
1177 1178 // Add left-to-right using the NAF optimization. See algorithm 3.77 from
1179 // [GECC].
1180 //
1181 // Point Q = ∞ (point at infinity).
1182 var q JacobianPoint
1183 m := k1Len
1184 if m < k2Len {
1185 m = k2Len
1186 }
1187 for i := 0; i < m; i++ {
1188 // Since k1 and k2 are potentially different lengths and the calculation
1189 // is being done left to right, pad the front of the shorter one with
1190 // 0s.
1191 var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte
1192 if i >= m-k1Len {
1193 k1BytePos, k1ByteNeg = k1PosNAF[i-(m-k1Len)], k1NegNAF[i-(m-k1Len)]
1194 }
1195 if i >= m-k2Len {
1196 k2BytePos, k2ByteNeg = k2PosNAF[i-(m-k2Len)], k2NegNAF[i-(m-k2Len)]
1197 }
1198 1199 for mask := uint8(1 << 7); mask > 0; mask >>= 1 {
1200 // Q = 2 * Q
1201 DoubleNonConst(&q, &q)
1202 1203 // Add or subtract the first point based on the signed digit of the
1204 // NAF representation of k1 at this bit position.
1205 //
1206 // +1: Q = Q + p1
1207 // -1: Q = Q - p1
1208 // 0: Q = Q (no change)
1209 if k1BytePos&mask == mask {
1210 AddNonConst(&q, p1, &q)
1211 } else if k1ByteNeg&mask == mask {
1212 AddNonConst(&q, p1Neg, &q)
1213 }
1214 1215 // Add or subtract the second point based on the signed digit of the
1216 // NAF representation of k2 at this bit position.
1217 //
1218 // +1: Q = Q + p2
1219 // -1: Q = Q - p2
1220 // 0: Q = Q (no change)
1221 if k2BytePos&mask == mask {
1222 AddNonConst(&q, p2, &q)
1223 } else if k2ByteNeg&mask == mask {
1224 AddNonConst(&q, p2Neg, &q)
1225 }
1226 }
1227 }
1228 1229 result.Set(&q)
1230 }
1231 1232 // ScalarBaseMultNonConst multiplies k*G where k is a scalar modulo the curve
1233 // order and G is the base point of the group and stores the result in the
1234 // provided Jacobian point.
1235 //
1236 // NOTE: The resulting point will be normalized.
1237 func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
1238 scalarBaseMultNonConst(k, result)
1239 }
1240 1241 // jacobianG is the secp256k1 base point converted to Jacobian coordinates and
1242 // is defined here to avoid repeatedly converting it.
1243 var jacobianG = func() JacobianPoint {
1244 var G JacobianPoint
1245 bigAffineToJacobian(curveParams.Gx, curveParams.Gy, &G)
1246 return G
1247 }()
1248 1249 // scalarBaseMultNonConstSlow computes k*G through ScalarMultNonConst.
1250 func scalarBaseMultNonConstSlow(k *ModNScalar, result *JacobianPoint) {
1251 ScalarMultNonConst(k, &jacobianG, result)
1252 }
1253 1254 // scalarBaseMultNonConstFast computes k*G through the precomputed lookup
1255 // tables.
1256 func scalarBaseMultNonConstFast(k *ModNScalar, result *JacobianPoint) {
1257 bytePoints := s256BytePoints()
1258 1259 // Start with the point at infinity.
1260 result.X.Zero()
1261 result.Y.Zero()
1262 result.Z.Zero()
1263 1264 // bytePoints has all 256 byte points for each 8-bit window. The strategy
1265 // is to add up the byte points. This is best understood by expressing k in
1266 // base-256 which it already sort of is. Each "digit" in the 8-bit window
1267 // can be looked up using bytePoints and added together.
1268 kb := k.Bytes()
1269 for i := 0; i < len(kb); i++ {
1270 pt := &bytePoints[i][kb[i]]
1271 AddNonConst(result, pt, result)
1272 }
1273 }
1274 1275 // isOnCurve returns whether or not the affine point (x,y) is on the curve.
1276 func isOnCurve(fx, fy *FieldVal) bool {
1277 // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7
1278 y2 := new(FieldVal).SquareVal(fy).Normalize()
1279 result := new(FieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize()
1280 return y2.Equals(result)
1281 }
1282 1283 // DecompressY attempts to calculate the Y coordinate for the given X coordinate
1284 // such that the result pair is a point on the secp256k1 curve. It adjusts Y
1285 // based on the desired oddness and returns whether or not it was successful
1286 // since not all X coordinates are valid.
1287 //
1288 // The magnitude of the provided X coordinate field value must be a max of 8 for
1289 // a correct result. The resulting Y field value will have a magnitude of 1.
1290 //
1291 // Preconditions:
1292 // - The input field value MUST have a max magnitude of 8
1293 // Output Normalized: Yes if the func returns true, no otherwise
1294 // Output Max Magnitude: 1
1295 func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool {
1296 // The curve equation for secp256k1 is: y^2 = x^3 + 7. Thus
1297 // y = +-sqrt(x^3 + 7).
1298 //
1299 // The x coordinate must be invalid if there is no square root for the
1300 // calculated rhs because it means the X coordinate is not for a point on
1301 // the curve.
1302 x3PlusB := new(FieldVal).SquareVal(x).Mul(x).AddInt(7)
1303 if hasSqrt := resultY.SquareRootVal(x3PlusB); !hasSqrt {
1304 return false
1305 }
1306 if resultY.Normalize().IsOdd() != odd {
1307 resultY.Negate(1).Normalize()
1308 }
1309 return true
1310 }
1311