curve.go 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943
  1. // Copyright (c) 2015-2021 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. package secp256k1
  6. import (
  7. "encoding/hex"
  8. "math/big"
  9. )
  10. // References:
  11. // [SECG]: Recommended Elliptic Curve Domain Parameters
  12. // https://www.secg.org/sec2-v2.pdf
  13. //
  14. // [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
  15. //
  16. // [BRID]: On Binary Representations of Integers with Digits -1, 0, 1
  17. // (Prodinger, Helmut)
  18. // All group operations are performed using Jacobian coordinates. For a given
  19. // (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
  20. // where x = x1/z1^2 and y = y1/z1^3.
  21. // hexToFieldVal converts the passed hex string into a FieldVal and will panic
  22. // if there is an error. This is only provided for the hard-coded constants so
  23. // errors in the source code can be detected. It will only (and must only) be
  24. // called with hard-coded values.
  25. func hexToFieldVal(s string) *FieldVal {
  26. b, err := hex.DecodeString(s)
  27. if err != nil {
  28. panic("invalid hex in source file: " + s)
  29. }
  30. var f FieldVal
  31. if overflow := f.SetByteSlice(b); overflow {
  32. panic("hex in source file overflows mod P: " + s)
  33. }
  34. return &f
  35. }
  36. var (
  37. // Next 6 constants are from Hal Finney's bitcointalk.org post:
  38. // https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565
  39. // May he rest in peace.
  40. //
  41. // They have also been independently derived from the code in the
  42. // EndomorphismVectors function in genstatics.go.
  43. endomorphismLambda = fromHex("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72")
  44. endomorphismBeta = hexToFieldVal("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee")
  45. endomorphismA1 = fromHex("3086d221a7d46bcde86c90e49284eb15")
  46. endomorphismB1 = fromHex("-e4437ed6010e88286f547fa90abfe4c3")
  47. endomorphismA2 = fromHex("114ca50f7a8e2f3f657c1108d9d44cfd8")
  48. endomorphismB2 = fromHex("3086d221a7d46bcde86c90e49284eb15")
  49. // Alternatively, the following parameters are valid as well, however, they
  50. // seem to be about 8% slower in practice.
  51. //
  52. // endomorphismLambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE")
  53. // endomorphismBeta = hexToFieldVal("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40")
  54. // endomorphismA1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3")
  55. // endomorphismB1 = fromHex("-3086D221A7D46BCDE86C90E49284EB15")
  56. // endomorphismA2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
  57. // endomorphismB2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
  58. )
  59. // JacobianPoint is an element of the group formed by the secp256k1 curve in
  60. // Jacobian projective coordinates and thus represents a point on the curve.
  61. type JacobianPoint struct {
  62. // The X coordinate in Jacobian projective coordinates. The affine point is
  63. // X/z^2.
  64. X FieldVal
  65. // The Y coordinate in Jacobian projective coordinates. The affine point is
  66. // Y/z^3.
  67. Y FieldVal
  68. // The Z coordinate in Jacobian projective coordinates.
  69. Z FieldVal
  70. }
  71. // MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z
  72. // coordinates.
  73. func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint {
  74. var p JacobianPoint
  75. p.X.Set(x)
  76. p.Y.Set(y)
  77. p.Z.Set(z)
  78. return p
  79. }
  80. // Set sets the Jacobian point to the provided point.
  81. func (p *JacobianPoint) Set(other *JacobianPoint) {
  82. p.X.Set(&other.X)
  83. p.Y.Set(&other.Y)
  84. p.Z.Set(&other.Z)
  85. }
  86. // ToAffine reduces the Z value of the existing point to 1 effectively
  87. // making it an affine coordinate in constant time. The point will be
  88. // normalized.
  89. func (p *JacobianPoint) ToAffine() {
  90. // Inversions are expensive and both point addition and point doubling
  91. // are faster when working with points that have a z value of one. So,
  92. // if the point needs to be converted to affine, go ahead and normalize
  93. // the point itself at the same time as the calculation is the same.
  94. var zInv, tempZ FieldVal
  95. zInv.Set(&p.Z).Inverse() // zInv = Z^-1
  96. tempZ.SquareVal(&zInv) // tempZ = Z^-2
  97. p.X.Mul(&tempZ) // X = X/Z^2 (mag: 1)
  98. p.Y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1)
  99. p.Z.SetInt(1) // Z = 1 (mag: 1)
  100. // Normalize the x and y values.
  101. p.X.Normalize()
  102. p.Y.Normalize()
  103. }
  104. // addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have
  105. // z values of 1 and stores the result in the provided result param. That is to
  106. // say result = p1 + p2. It performs faster addition than the generic add
  107. // routine since less arithmetic is needed due to the ability to avoid the z
  108. // value multiplications.
  109. //
  110. // NOTE: The points must be normalized for this function to return the correct
  111. // result. The resulting point will be normalized.
  112. func addZ1AndZ2EqualsOne(p1, p2, result *JacobianPoint) {
  113. // To compute the point addition efficiently, this implementation splits
  114. // the equation into intermediate elements which are used to minimize
  115. // the number of field multiplications using the method shown at:
  116. // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
  117. //
  118. // In particular it performs the calculations using the following:
  119. // H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I
  120. // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H
  121. //
  122. // This results in a cost of 4 field multiplications, 2 field squarings,
  123. // 6 field additions, and 5 integer multiplications.
  124. x1, y1 := &p1.X, &p1.Y
  125. x2, y2 := &p2.X, &p2.Y
  126. x3, y3, z3 := &result.X, &result.Y, &result.Z
  127. // When the x coordinates are the same for two points on the curve, the
  128. // y coordinates either must be the same, in which case it is point
  129. // doubling, or they are opposite and the result is the point at
  130. // infinity per the group law for elliptic curve cryptography.
  131. if x1.Equals(x2) {
  132. if y1.Equals(y2) {
  133. // Since x1 == x2 and y1 == y2, point doubling must be
  134. // done, otherwise the addition would end up dividing
  135. // by zero.
  136. DoubleNonConst(p1, result)
  137. return
  138. }
  139. // Since x1 == x2 and y1 == -y2, the sum is the point at
  140. // infinity per the group law.
  141. x3.SetInt(0)
  142. y3.SetInt(0)
  143. z3.SetInt(0)
  144. return
  145. }
  146. // Calculate X3, Y3, and Z3 according to the intermediate elements
  147. // breakdown above.
  148. var h, i, j, r, v FieldVal
  149. var negJ, neg2V, negX3 FieldVal
  150. h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3)
  151. i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4)
  152. j.Mul2(&h, &i) // J = H*I (mag: 1)
  153. r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6)
  154. v.Mul2(x1, &i) // V = X1*I (mag: 1)
  155. negJ.Set(&j).Negate(1) // negJ = -J (mag: 2)
  156. neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3)
  157. x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6)
  158. negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7)
  159. j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3)
  160. y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4)
  161. z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6)
  162. // Normalize the resulting field values to a magnitude of 1 as needed.
  163. x3.Normalize()
  164. y3.Normalize()
  165. z3.Normalize()
  166. }
  167. // addZ1EqualsZ2 adds two Jacobian points that are already known to have the
  168. // same z value and stores the result in the provided result param. That is to
  169. // say result = p1 + p2. It performs faster addition than the generic add
  170. // routine since less arithmetic is needed due to the known equivalence.
  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 addZ1EqualsZ2(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 a slightly modified version
  178. // of the method shown at:
  179. // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
  180. //
  181. // In particular it performs the calculations using the following:
  182. // A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B
  183. // X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A
  184. //
  185. // This results in a cost of 5 field multiplications, 2 field squarings,
  186. // 9 field additions, and 0 integer multiplications.
  187. x1, y1, z1 := &p1.X, &p1.Y, &p1.Z
  188. x2, y2 := &p2.X, &p2.Y
  189. x3, y3, z3 := &result.X, &result.Y, &result.Z
  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. // Since x1 == x2 and y1 == -y2, the sum is the point at
  203. // infinity per the group law.
  204. x3.SetInt(0)
  205. y3.SetInt(0)
  206. z3.SetInt(0)
  207. return
  208. }
  209. // Calculate X3, Y3, and Z3 according to the intermediate elements
  210. // breakdown above.
  211. var a, b, c, d, e, f FieldVal
  212. var negX1, negY1, negE, negX3 FieldVal
  213. negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
  214. negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
  215. a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3)
  216. b.SquareVal(&a) // B = A^2 (mag: 1)
  217. c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3)
  218. d.SquareVal(&c) // D = C^2 (mag: 1)
  219. e.Mul2(x1, &b) // E = X1*B (mag: 1)
  220. negE.Set(&e).Negate(1) // negE = -E (mag: 2)
  221. f.Mul2(x2, &b) // F = X2*B (mag: 1)
  222. x3.Add2(&e, &f).Negate(3).Add(&d) // X3 = D-E-F (mag: 5)
  223. negX3.Set(x3).Negate(5).Normalize() // negX3 = -X3 (mag: 1)
  224. y3.Set(y1).Mul(f.Add(&negE)).Negate(3) // Y3 = -(Y1*(F-E)) (mag: 4)
  225. y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 5)
  226. z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1)
  227. // Normalize the resulting field values to a magnitude of 1 as needed.
  228. x3.Normalize()
  229. y3.Normalize()
  230. z3.Normalize()
  231. }
  232. // addZ2EqualsOne adds two Jacobian points when the second point is already
  233. // known to have a z value of 1 (and the z value for the first point is not 1)
  234. // and stores the result in the provided result param. That is to say result =
  235. // p1 + p2. It performs faster addition than the generic add routine since
  236. // less arithmetic is needed due to the ability to avoid multiplications by the
  237. // second point's z value.
  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 addZ2EqualsOne(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 the method shown at:
  245. // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
  246. //
  247. // In particular it performs the calculations using the following:
  248. // Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2,
  249. // I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I
  250. // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH
  251. //
  252. // This results in a cost of 7 field multiplications, 4 field squarings,
  253. // 9 field additions, and 4 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. // When the x coordinates are the same for two points on the curve, the
  258. // y coordinates either must be the same, in which case it is point
  259. // doubling, or they are opposite and the result is the point at
  260. // infinity per the group law for elliptic curve cryptography. Since
  261. // any number of Jacobian coordinates can represent the same affine
  262. // point, the x and y values need to be converted to like terms. Due to
  263. // the assumption made for this function that the second point has a z
  264. // value of 1 (z2=1), the first point is already "converted".
  265. var z1z1, u2, s2 FieldVal
  266. z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
  267. u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
  268. s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
  269. if x1.Equals(&u2) {
  270. if y1.Equals(&s2) {
  271. // Since x1 == x2 and y1 == y2, point doubling must be
  272. // done, otherwise the addition would end up dividing
  273. // by zero.
  274. DoubleNonConst(p1, result)
  275. return
  276. }
  277. // Since x1 == x2 and y1 == -y2, the sum is the point at
  278. // infinity per the group law.
  279. x3.SetInt(0)
  280. y3.SetInt(0)
  281. z3.SetInt(0)
  282. return
  283. }
  284. // Calculate X3, Y3, and Z3 according to the intermediate elements
  285. // breakdown above.
  286. var h, hh, i, j, r, rr, v FieldVal
  287. var negX1, negY1, negX3 FieldVal
  288. negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
  289. h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3)
  290. hh.SquareVal(&h) // HH = H^2 (mag: 1)
  291. i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4)
  292. j.Mul2(&h, &i) // J = H*I (mag: 1)
  293. negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
  294. r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6)
  295. rr.SquareVal(&r) // rr = r^2 (mag: 1)
  296. v.Mul2(x1, &i) // V = X1*I (mag: 1)
  297. x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
  298. x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
  299. negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
  300. y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3)
  301. y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
  302. z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1)
  303. z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4)
  304. // Normalize the resulting field values to a magnitude of 1 as needed.
  305. x3.Normalize()
  306. y3.Normalize()
  307. z3.Normalize()
  308. }
  309. // addGeneric adds two Jacobian points without any assumptions about the z
  310. // values of the two points and stores the result in the provided result param.
  311. // That is to say result = p1 + p2. It is the slowest of the add routines due
  312. // to requiring the most arithmetic.
  313. //
  314. // NOTE: The points must be normalized for this function to return the correct
  315. // result. The resulting point will be normalized.
  316. func addGeneric(p1, p2, result *JacobianPoint) {
  317. // To compute the point addition efficiently, this implementation splits
  318. // the equation into intermediate elements which are used to minimize
  319. // the number of field multiplications using the method shown at:
  320. // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
  321. //
  322. // In particular it performs the calculations using the following:
  323. // Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2
  324. // S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1)
  325. // V = U1*I
  326. // X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H
  327. //
  328. // This results in a cost of 11 field multiplications, 5 field squarings,
  329. // 9 field additions, and 4 integer multiplications.
  330. x1, y1, z1 := &p1.X, &p1.Y, &p1.Z
  331. x2, y2, z2 := &p2.X, &p2.Y, &p2.Z
  332. x3, y3, z3 := &result.X, &result.Y, &result.Z
  333. // When the x coordinates are the same for two points on the curve, the
  334. // y coordinates either must be the same, in which case it is point
  335. // doubling, or they are opposite and the result is the point at
  336. // infinity. Since any number of Jacobian coordinates can represent the
  337. // same affine point, the x and y values need to be converted to like
  338. // terms.
  339. var z1z1, z2z2, u1, u2, s1, s2 FieldVal
  340. z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
  341. z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1)
  342. u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1)
  343. u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
  344. s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1)
  345. s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
  346. if u1.Equals(&u2) {
  347. if s1.Equals(&s2) {
  348. // Since x1 == x2 and y1 == y2, point doubling must be
  349. // done, otherwise the addition would end up dividing
  350. // by zero.
  351. DoubleNonConst(p1, result)
  352. return
  353. }
  354. // Since x1 == x2 and y1 == -y2, the sum is the point at
  355. // infinity per the group law.
  356. x3.SetInt(0)
  357. y3.SetInt(0)
  358. z3.SetInt(0)
  359. return
  360. }
  361. // Calculate X3, Y3, and Z3 according to the intermediate elements
  362. // breakdown above.
  363. var h, i, j, r, rr, v FieldVal
  364. var negU1, negS1, negX3 FieldVal
  365. negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2)
  366. h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3)
  367. i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 2)
  368. j.Mul2(&h, &i) // J = H*I (mag: 1)
  369. negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2)
  370. r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6)
  371. rr.SquareVal(&r) // rr = r^2 (mag: 1)
  372. v.Mul2(&u1, &i) // V = U1*I (mag: 1)
  373. x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
  374. x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
  375. negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
  376. y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3)
  377. y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
  378. z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1)
  379. z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4)
  380. z3.Mul(&h) // Z3 = Z3*H (mag: 1)
  381. // Normalize the resulting field values to a magnitude of 1 as needed.
  382. x3.Normalize()
  383. y3.Normalize()
  384. z3.Normalize()
  385. }
  386. // AddNonConst adds the passed Jacobian points together and stores the result in
  387. // the provided result param in *non-constant* time.
  388. //
  389. // NOTE: The points must be normalized for this function to return the correct
  390. // result. The resulting point will be normalized.
  391. func AddNonConst(p1, p2, result *JacobianPoint) {
  392. // A point at infinity is the identity according to the group law for
  393. // elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
  394. if (p1.X.IsZero() && p1.Y.IsZero()) || p1.Z.IsZero() {
  395. result.Set(p2)
  396. return
  397. }
  398. if (p2.X.IsZero() && p2.Y.IsZero()) || p2.Z.IsZero() {
  399. result.Set(p1)
  400. return
  401. }
  402. // Faster point addition can be achieved when certain assumptions are
  403. // met. For example, when both points have the same z value, arithmetic
  404. // on the z values can be avoided. This section thus checks for these
  405. // conditions and calls an appropriate add function which is accelerated
  406. // by using those assumptions.
  407. isZ1One := p1.Z.IsOne()
  408. isZ2One := p2.Z.IsOne()
  409. switch {
  410. case isZ1One && isZ2One:
  411. addZ1AndZ2EqualsOne(p1, p2, result)
  412. return
  413. case p1.Z.Equals(&p2.Z):
  414. addZ1EqualsZ2(p1, p2, result)
  415. return
  416. case isZ2One:
  417. addZ2EqualsOne(p1, p2, result)
  418. return
  419. }
  420. // None of the above assumptions are true, so fall back to generic
  421. // point addition.
  422. addGeneric(p1, p2, result)
  423. }
  424. // doubleZ1EqualsOne performs point doubling on the passed Jacobian point when
  425. // the point is already known to have a z value of 1 and stores the result in
  426. // the provided result param. That is to say result = 2*p. It performs faster
  427. // point doubling than the generic routine since less arithmetic is needed due
  428. // to the ability to avoid multiplication by the z value.
  429. //
  430. // NOTE: The resulting point will be normalized.
  431. func doubleZ1EqualsOne(p, result *JacobianPoint) {
  432. // This function uses the assumptions that z1 is 1, thus the point
  433. // doubling formulas reduce to:
  434. //
  435. // X3 = (3*X1^2)^2 - 8*X1*Y1^2
  436. // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
  437. // Z3 = 2*Y1
  438. //
  439. // To compute the above efficiently, this implementation splits the
  440. // equation into intermediate elements which are used to minimize the
  441. // number of field multiplications in favor of field squarings which
  442. // are roughly 35% faster than field multiplications with the current
  443. // implementation at the time this was written.
  444. //
  445. // This uses a slightly modified version of the method shown at:
  446. // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl
  447. //
  448. // In particular it performs the calculations using the following:
  449. // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
  450. // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
  451. // Z3 = 2*Y1
  452. //
  453. // This results in a cost of 1 field multiplication, 5 field squarings,
  454. // 6 field additions, and 5 integer multiplications.
  455. x1, y1 := &p.X, &p.Y
  456. x3, y3, z3 := &result.X, &result.Y, &result.Z
  457. var a, b, c, d, e, f FieldVal
  458. z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2)
  459. a.SquareVal(x1) // A = X1^2 (mag: 1)
  460. b.SquareVal(y1) // B = Y1^2 (mag: 1)
  461. c.SquareVal(&b) // C = B^2 (mag: 1)
  462. b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
  463. d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
  464. d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
  465. e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
  466. f.SquareVal(&e) // F = E^2 (mag: 1)
  467. x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
  468. x3.Add(&f) // X3 = F+X3 (mag: 18)
  469. f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
  470. y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
  471. y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
  472. // Normalize the field values back to a magnitude of 1.
  473. x3.Normalize()
  474. y3.Normalize()
  475. z3.Normalize()
  476. }
  477. // doubleGeneric performs point doubling on the passed Jacobian point without
  478. // any assumptions about the z value and stores the result in the provided
  479. // result param. That is to say result = 2*p. It is the slowest of the point
  480. // doubling routines due to requiring the most arithmetic.
  481. //
  482. // NOTE: The resulting point will be normalized.
  483. func doubleGeneric(p, result *JacobianPoint) {
  484. // Point doubling formula for Jacobian coordinates for the secp256k1
  485. // curve:
  486. //
  487. // X3 = (3*X1^2)^2 - 8*X1*Y1^2
  488. // Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
  489. // Z3 = 2*Y1*Z1
  490. //
  491. // To compute the above efficiently, this implementation splits the
  492. // equation into intermediate elements which are used to minimize the
  493. // number of field multiplications in favor of field squarings which
  494. // are roughly 35% faster than field multiplications with the current
  495. // implementation at the time this was written.
  496. //
  497. // This uses a slightly modified version of the method shown at:
  498. // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
  499. //
  500. // In particular it performs the calculations using the following:
  501. // A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
  502. // E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
  503. // Z3 = 2*Y1*Z1
  504. //
  505. // This results in a cost of 1 field multiplication, 5 field squarings,
  506. // 6 field additions, and 5 integer multiplications.
  507. x1, y1, z1 := &p.X, &p.Y, &p.Z
  508. x3, y3, z3 := &result.X, &result.Y, &result.Z
  509. var a, b, c, d, e, f FieldVal
  510. z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2)
  511. a.SquareVal(x1) // A = X1^2 (mag: 1)
  512. b.SquareVal(y1) // B = Y1^2 (mag: 1)
  513. c.SquareVal(&b) // C = B^2 (mag: 1)
  514. b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
  515. d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
  516. d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
  517. e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
  518. f.SquareVal(&e) // F = E^2 (mag: 1)
  519. x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
  520. x3.Add(&f) // X3 = F+X3 (mag: 18)
  521. f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
  522. y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
  523. y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
  524. // Normalize the field values back to a magnitude of 1.
  525. x3.Normalize()
  526. y3.Normalize()
  527. z3.Normalize()
  528. }
  529. // DoubleNonConst doubles the passed Jacobian point and stores the result in the
  530. // provided result parameter in *non-constant* time.
  531. //
  532. // NOTE: The point must be normalized for this function to return the correct
  533. // result. The resulting point will be normalized.
  534. func DoubleNonConst(p, result *JacobianPoint) {
  535. // Doubling a point at infinity is still infinity.
  536. if p.Y.IsZero() || p.Z.IsZero() {
  537. result.X.SetInt(0)
  538. result.Y.SetInt(0)
  539. result.Z.SetInt(0)
  540. return
  541. }
  542. // Slightly faster point doubling can be achieved when the z value is 1
  543. // by avoiding the multiplication on the z value. This section calls
  544. // a point doubling function which is accelerated by using that
  545. // assumption when possible.
  546. if p.Z.IsOne() {
  547. doubleZ1EqualsOne(p, result)
  548. return
  549. }
  550. // Fall back to generic point doubling which works with arbitrary z
  551. // values.
  552. doubleGeneric(p, result)
  553. }
  554. // splitK returns a balanced length-two representation of k and their signs.
  555. // This is algorithm 3.74 from [GECC].
  556. //
  557. // One thing of note about this algorithm is that no matter what c1 and c2 are,
  558. // the final equation of k = k1 + k2 * lambda (mod n) will hold. This is
  559. // provable mathematically due to how a1/b1/a2/b2 are computed.
  560. //
  561. // c1 and c2 are chosen to minimize the max(k1,k2).
  562. func splitK(k []byte) ([]byte, []byte, int, int) {
  563. // All math here is done with big.Int, which is slow.
  564. // At some point, it might be useful to write something similar to
  565. // FieldVal but for N instead of P as the prime field if this ends up
  566. // being a bottleneck.
  567. bigIntK := new(big.Int)
  568. c1, c2 := new(big.Int), new(big.Int)
  569. tmp1, tmp2 := new(big.Int), new(big.Int)
  570. k1, k2 := new(big.Int), new(big.Int)
  571. bigIntK.SetBytes(k)
  572. // c1 = round(b2 * k / n) from step 4.
  573. // Rounding isn't really necessary and costs too much, hence skipped
  574. c1.Mul(endomorphismB2, bigIntK)
  575. c1.Div(c1, curveParams.N)
  576. // c2 = round(b1 * k / n) from step 4 (sign reversed to optimize one step)
  577. // Rounding isn't really necessary and costs too much, hence skipped
  578. c2.Mul(endomorphismB1, bigIntK)
  579. c2.Div(c2, curveParams.N)
  580. // k1 = k - c1 * a1 - c2 * a2 from step 5 (note c2's sign is reversed)
  581. tmp1.Mul(c1, endomorphismA1)
  582. tmp2.Mul(c2, endomorphismA2)
  583. k1.Sub(bigIntK, tmp1)
  584. k1.Add(k1, tmp2)
  585. // k2 = - c1 * b1 - c2 * b2 from step 5 (note c2's sign is reversed)
  586. tmp1.Mul(c1, endomorphismB1)
  587. tmp2.Mul(c2, endomorphismB2)
  588. k2.Sub(tmp2, tmp1)
  589. // Note Bytes() throws out the sign of k1 and k2. This matters
  590. // since k1 and/or k2 can be negative. Hence, we pass that
  591. // back separately.
  592. return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign()
  593. }
  594. // nafScalar represents a positive integer up to a maximum value of 2^256 - 1
  595. // encoded in non-adjacent form.
  596. //
  597. // NAF is a signed-digit representation where each digit can be +1, 0, or -1.
  598. //
  599. // In order to efficiently encode that information, this type uses two arrays, a
  600. // "positive" array where set bits represent the +1 signed digits and a
  601. // "negative" array where set bits represent the -1 signed digits. 0 is
  602. // represented by neither array having a bit set in that position.
  603. //
  604. // The Pos and Neg methods return the aforementioned positive and negative
  605. // arrays, respectively.
  606. type nafScalar struct {
  607. // pos houses the positive portion of the representation. An additional
  608. // byte is required for the positive portion because the NAF encoding can be
  609. // up to 1 bit longer than the normal binary encoding of the value.
  610. //
  611. // neg houses the negative portion of the representation. Even though the
  612. // additional byte is not required for the negative portion, since it can
  613. // never exceed the length of the normal binary encoding of the value,
  614. // keeping the same length for positive and negative portions simplifies
  615. // working with the representation and allows extra conditional branches to
  616. // be avoided.
  617. //
  618. // start and end specify the starting and ending index to use within the pos
  619. // and neg arrays, respectively. This allows fixed size arrays to be used
  620. // versus needing to dynamically allocate space on the heap.
  621. //
  622. // NOTE: The fields are defined in the order that they are to minimize the
  623. // padding on 32-bit and 64-bit platforms.
  624. pos [33]byte
  625. start, end uint8
  626. neg [33]byte
  627. }
  628. // Pos returns the bytes of the encoded value with bits set in the positions
  629. // that represent a signed digit of +1.
  630. func (s *nafScalar) Pos() []byte {
  631. return s.pos[s.start:s.end]
  632. }
  633. // Neg returns the bytes of the encoded value with bits set in the positions
  634. // that represent a signed digit of -1.
  635. func (s *nafScalar) Neg() []byte {
  636. return s.neg[s.start:s.end]
  637. }
  638. // naf takes a positive integer up to a maximum value of 2^256 - 1 and returns
  639. // its non-adjacent form (NAF), which is a unique signed-digit representation
  640. // such that no two consecutive digits are nonzero. See the documentation for
  641. // the returned type for details on how the representation is encoded
  642. // efficiently and how to interpret it
  643. //
  644. // NAF is useful in that it has the fewest nonzero digits of any signed digit
  645. // representation, only 1/3rd of its digits are nonzero on average, and at least
  646. // half of the digits will be 0.
  647. //
  648. // The aforementioned properties are particularly beneficial for optimizing
  649. // elliptic curve point multiplication because they effectively minimize the
  650. // number of required point additions in exchange for needing to perform a mix
  651. // of fewer point additions and subtractions and possibly one additional point
  652. // doubling. This is an excellent tradeoff because subtraction of points has
  653. // the same computational complexity as addition of points and point doubling is
  654. // faster than both.
  655. func naf(k []byte) nafScalar {
  656. // Strip leading zero bytes.
  657. for len(k) > 0 && k[0] == 0x00 {
  658. k = k[1:]
  659. }
  660. // The non-adjacent form (NAF) of a positive integer k is an expression
  661. // k = ∑_(i=0, l-1) k_i * 2^i where k_i ∈ {0,±1}, k_(l-1) != 0, and no two
  662. // consecutive digits k_i are nonzero.
  663. //
  664. // The traditional method of computing the NAF of a positive integer is
  665. // given by algorithm 3.30 in [GECC]. It consists of repeatedly dividing k
  666. // by 2 and choosing the remainder so that the quotient (k−r)/2 is even
  667. // which ensures the next NAF digit is 0. This requires log_2(k) steps.
  668. //
  669. // However, in [BRID], Prodinger notes that a closed form expression for the
  670. // NAF representation is the bitwise difference 3k/2 - k/2. This is more
  671. // efficient as it can be computed in O(1) versus the O(log(n)) of the
  672. // traditional approach.
  673. //
  674. // The following code makes use of that formula to compute the NAF more
  675. // efficiently.
  676. //
  677. // To understand the logic here, observe that the only way the NAF has a
  678. // nonzero digit at a given bit is when either 3k/2 or k/2 has a bit set in
  679. // that position, but not both. In other words, the result of a bitwise
  680. // xor. This can be seen simply by considering that when the bits are the
  681. // same, the subtraction is either 0-0 or 1-1, both of which are 0.
  682. //
  683. // Further, observe that the "+1" digits in the result are contributed by
  684. // 3k/2 while the "-1" digits are from k/2. So, they can be determined by
  685. // taking the bitwise and of each respective value with the result of the
  686. // xor which identifies which bits are nonzero.
  687. //
  688. // Using that information, this loops backwards from the least significant
  689. // byte to the most significant byte while performing the aforementioned
  690. // calculations by propagating the potential carry and high order bit from
  691. // the next word during the right shift.
  692. kLen := len(k)
  693. var result nafScalar
  694. var carry uint8
  695. for byteNum := kLen - 1; byteNum >= 0; byteNum-- {
  696. // Calculate k/2. Notice the carry from the previous word is added and
  697. // the low order bit from the next word is shifted in accordingly.
  698. kc := uint16(k[byteNum]) + uint16(carry)
  699. var nextWord uint8
  700. if byteNum > 0 {
  701. nextWord = k[byteNum-1]
  702. }
  703. halfK := kc>>1 | uint16(nextWord<<7)
  704. // Calculate 3k/2 and determine the non-zero digits in the result.
  705. threeHalfK := kc + halfK
  706. nonZeroResultDigits := threeHalfK ^ halfK
  707. // Determine the signed digits {0, ±1}.
  708. result.pos[byteNum+1] = uint8(threeHalfK & nonZeroResultDigits)
  709. result.neg[byteNum+1] = uint8(halfK & nonZeroResultDigits)
  710. // Propagate the potential carry from the 3k/2 calculation.
  711. carry = uint8(threeHalfK >> 8)
  712. }
  713. result.pos[0] = carry
  714. // Set the starting and ending positions within the fixed size arrays to
  715. // identify the bytes that are actually used. This is important since the
  716. // encoding is big endian and thus trailing zero bytes changes its value.
  717. result.start = 1 - carry
  718. result.end = uint8(kLen + 1)
  719. return result
  720. }
  721. // ScalarMultNonConst multiplies k*P where k is a big endian integer modulo the
  722. // curve order and P is a point in Jacobian projective coordinates and stores
  723. // the result in the provided Jacobian point.
  724. //
  725. // NOTE: The point must be normalized for this function to return the correct
  726. // result. The resulting point will be normalized.
  727. func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) {
  728. // Decompose K into k1 and k2 in order to halve the number of EC ops.
  729. // See Algorithm 3.74 in [GECC].
  730. kBytes := k.Bytes()
  731. k1, k2, signK1, signK2 := splitK(kBytes[:])
  732. zeroArray32(&kBytes)
  733. // The main equation here to remember is:
  734. // k * P = k1 * P + k2 * ϕ(P)
  735. //
  736. // P1 below is P in the equation, P2 below is ϕ(P) in the equation
  737. p1, p1Neg := new(JacobianPoint), new(JacobianPoint)
  738. p1.Set(point)
  739. p1Neg.Set(p1)
  740. p1Neg.Y.Negate(1).Normalize()
  741. // NOTE: ϕ(x,y) = (βx,y). The Jacobian z coordinates are the same, so this
  742. // math goes through.
  743. p2, p2Neg := new(JacobianPoint), new(JacobianPoint)
  744. p2.Set(p1)
  745. p2.X.Mul(endomorphismBeta).Normalize()
  746. p2Neg.Set(p2)
  747. p2Neg.Y.Negate(1).Normalize()
  748. // Flip the positive and negative values of the points as needed
  749. // depending on the signs of k1 and k2. As mentioned in the equation
  750. // above, each of k1 and k2 are multiplied by the respective point.
  751. // Since -k * P is the same thing as k * -P, and the group law for
  752. // elliptic curves states that P(x, y) = -P(x, -y), it's faster and
  753. // simplifies the code to just make the point negative.
  754. if signK1 == -1 {
  755. p1, p1Neg = p1Neg, p1
  756. }
  757. if signK2 == -1 {
  758. p2, p2Neg = p2Neg, p2
  759. }
  760. // NAF versions of k1 and k2 should have a lot more zeros.
  761. //
  762. // The Pos version of the bytes contain the +1s and the Neg versions
  763. // contain the -1s.
  764. k1NAF, k2NAF := naf(k1), naf(k2)
  765. k1PosNAF, k1NegNAF := k1NAF.Pos(), k1NAF.Neg()
  766. k2PosNAF, k2NegNAF := k2NAF.Pos(), k2NAF.Neg()
  767. k1Len, k2Len := len(k1PosNAF), len(k2PosNAF)
  768. m := k1Len
  769. if m < k2Len {
  770. m = k2Len
  771. }
  772. // Point Q = ∞ (point at infinity).
  773. var q JacobianPoint
  774. // Add left-to-right using the NAF optimization. See algorithm 3.77
  775. // from [GECC]. This should be faster overall since there will be a lot
  776. // more instances of 0, hence reducing the number of Jacobian additions
  777. // at the cost of 1 possible extra doubling.
  778. for i := 0; i < m; i++ {
  779. // Since k1 and k2 are potentially different lengths and the calculation
  780. // is being done left to right, pad the front of the shorter one with
  781. // 0s.
  782. var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte
  783. if i >= m-k1Len {
  784. k1BytePos, k1ByteNeg = k1PosNAF[i-(m-k1Len)], k1NegNAF[i-(m-k1Len)]
  785. }
  786. if i >= m-k2Len {
  787. k2BytePos, k2ByteNeg = k2PosNAF[i-(m-k2Len)], k2NegNAF[i-(m-k2Len)]
  788. }
  789. for bit, mask := 7, uint8(1<<7); bit >= 0; bit, mask = bit-1, mask>>1 {
  790. // Q = 2 * Q
  791. DoubleNonConst(&q, &q)
  792. // Add or subtract the first point based on the signed digit of the
  793. // NAF representation of k1 at this bit position.
  794. //
  795. // +1: Q = Q + p1
  796. // -1: Q = Q - p1
  797. // 0: Q = Q (no change)
  798. if k1BytePos&mask == mask {
  799. AddNonConst(&q, p1, &q)
  800. } else if k1ByteNeg&mask == mask {
  801. AddNonConst(&q, p1Neg, &q)
  802. }
  803. // Add or subtract the second point based on the signed digit of the
  804. // NAF representation of k2 at this bit position.
  805. //
  806. // +1: Q = Q + p2
  807. // -1: Q = Q - p2
  808. // 0: Q = Q (no change)
  809. if k2BytePos&mask == mask {
  810. AddNonConst(&q, p2, &q)
  811. } else if k2ByteNeg&mask == mask {
  812. AddNonConst(&q, p2Neg, &q)
  813. }
  814. }
  815. }
  816. result.Set(&q)
  817. }
  818. // ScalarBaseMultNonConst multiplies k*G where G is the base point of the group
  819. // and k is a big endian integer. The result is stored in Jacobian coordinates
  820. // (x1, y1, z1).
  821. //
  822. // NOTE: The resulting point will be normalized.
  823. func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) {
  824. bytePoints := s256BytePoints()
  825. // Point Q = ∞ (point at infinity).
  826. var q JacobianPoint
  827. // curve.bytePoints has all 256 byte points for each 8-bit window. The
  828. // strategy is to add up the byte points. This is best understood by
  829. // expressing k in base-256 which it already sort of is. Each "digit" in
  830. // the 8-bit window can be looked up using bytePoints and added together.
  831. var pt JacobianPoint
  832. for i, byteVal := range k.Bytes() {
  833. p := bytePoints[i][byteVal]
  834. pt.X.Set(&p[0])
  835. pt.Y.Set(&p[1])
  836. pt.Z.SetInt(1)
  837. AddNonConst(&q, &pt, &q)
  838. }
  839. result.Set(&q)
  840. }
  841. // isOnCurve returns whether or not the affine point (x,y) is on the curve.
  842. func isOnCurve(fx, fy *FieldVal) bool {
  843. // Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7
  844. y2 := new(FieldVal).SquareVal(fy).Normalize()
  845. result := new(FieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize()
  846. return y2.Equals(result)
  847. }
  848. // DecompressY attempts to calculate the Y coordinate for the given X coordinate
  849. // such that the result pair is a point on the secp256k1 curve. It adjusts Y
  850. // based on the desired oddness and returns whether or not it was successful
  851. // since not all X coordinates are valid.
  852. //
  853. // The magnitude of the provided X coordinate field val must be a max of 8 for a
  854. // correct result. The resulting Y field val will have a max magnitude of 2.
  855. func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool {
  856. // The curve equation for secp256k1 is: y^2 = x^3 + 7. Thus
  857. // y = +-sqrt(x^3 + 7).
  858. //
  859. // The x coordinate must be invalid if there is no square root for the
  860. // calculated rhs because it means the X coordinate is not for a point on
  861. // the curve.
  862. x3PlusB := new(FieldVal).SquareVal(x).Mul(x).AddInt(7)
  863. if hasSqrt := resultY.SquareRootVal(x3PlusB); !hasSqrt {
  864. return false
  865. }
  866. if resultY.Normalize().IsOdd() != odd {
  867. resultY.Negate(1)
  868. }
  869. return true
  870. }