Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

259 wiersze
5.4 KiB

  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package bn256
  5. import (
  6. "math/big"
  7. )
  8. // twistPoint implements the elliptic curve y²=x³+3/ξ over GF(p²). Points are
  9. // kept in Jacobian form and t=z² when valid. The group G₂ is the set of
  10. // n-torsion points of this curve over GF(p²) (where n = Order)
  11. type twistPoint struct {
  12. x, y, z, t *gfP2
  13. }
  14. var twistB = &gfP2{
  15. bigFromBase10("6500054969564660373279643874235990574282535810762300357187714502686418407178"),
  16. bigFromBase10("45500384786952622612957507119651934019977750675336102500314001518804928850249"),
  17. }
  18. // twistGen is the generator of group G₂.
  19. var twistGen = &twistPoint{
  20. &gfP2{
  21. bigFromBase10("21167961636542580255011770066570541300993051739349375019639421053990175267184"),
  22. bigFromBase10("64746500191241794695844075326670126197795977525365406531717464316923369116492"),
  23. },
  24. &gfP2{
  25. bigFromBase10("20666913350058776956210519119118544732556678129809273996262322366050359951122"),
  26. bigFromBase10("17778617556404439934652658462602675281523610326338642107814333856843981424549"),
  27. },
  28. &gfP2{
  29. bigFromBase10("0"),
  30. bigFromBase10("1"),
  31. },
  32. &gfP2{
  33. bigFromBase10("0"),
  34. bigFromBase10("1"),
  35. },
  36. }
  37. func newTwistPoint(pool *bnPool) *twistPoint {
  38. return &twistPoint{
  39. newGFp2(pool),
  40. newGFp2(pool),
  41. newGFp2(pool),
  42. newGFp2(pool),
  43. }
  44. }
  45. func (c *twistPoint) String() string {
  46. return "(" + c.x.String() + ", " + c.y.String() + ", " + c.z.String() + ")"
  47. }
  48. func (c *twistPoint) Put(pool *bnPool) {
  49. c.x.Put(pool)
  50. c.y.Put(pool)
  51. c.z.Put(pool)
  52. c.t.Put(pool)
  53. }
  54. func (c *twistPoint) Set(a *twistPoint) {
  55. c.x.Set(a.x)
  56. c.y.Set(a.y)
  57. c.z.Set(a.z)
  58. c.t.Set(a.t)
  59. }
  60. // IsOnCurve returns true iff c is on the curve where c must be in affine form.
  61. func (c *twistPoint) IsOnCurve() bool {
  62. pool := new(bnPool)
  63. yy := newGFp2(pool).Square(c.y, pool)
  64. xxx := newGFp2(pool).Square(c.x, pool)
  65. xxx.Mul(xxx, c.x, pool)
  66. yy.Sub(yy, xxx)
  67. yy.Sub(yy, twistB)
  68. yy.Minimal()
  69. return yy.x.Sign() == 0 && yy.y.Sign() == 0
  70. }
  71. func (c *twistPoint) SetInfinity() {
  72. c.z.SetZero()
  73. }
  74. func (c *twistPoint) IsInfinity() bool {
  75. return c.z.IsZero()
  76. }
  77. func (c *twistPoint) Add(a, b *twistPoint, pool *bnPool) {
  78. // For additional comments, see the same function in curve.go.
  79. if a.IsInfinity() {
  80. c.Set(b)
  81. return
  82. }
  83. if b.IsInfinity() {
  84. c.Set(a)
  85. return
  86. }
  87. // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
  88. z1z1 := newGFp2(pool).Square(a.z, pool)
  89. z2z2 := newGFp2(pool).Square(b.z, pool)
  90. u1 := newGFp2(pool).Mul(a.x, z2z2, pool)
  91. u2 := newGFp2(pool).Mul(b.x, z1z1, pool)
  92. t := newGFp2(pool).Mul(b.z, z2z2, pool)
  93. s1 := newGFp2(pool).Mul(a.y, t, pool)
  94. t.Mul(a.z, z1z1, pool)
  95. s2 := newGFp2(pool).Mul(b.y, t, pool)
  96. h := newGFp2(pool).Sub(u2, u1)
  97. xEqual := h.IsZero()
  98. t.Add(h, h)
  99. i := newGFp2(pool).Square(t, pool)
  100. j := newGFp2(pool).Mul(h, i, pool)
  101. t.Sub(s2, s1)
  102. yEqual := t.IsZero()
  103. if xEqual && yEqual {
  104. c.Double(a, pool)
  105. return
  106. }
  107. r := newGFp2(pool).Add(t, t)
  108. v := newGFp2(pool).Mul(u1, i, pool)
  109. t4 := newGFp2(pool).Square(r, pool)
  110. t.Add(v, v)
  111. t6 := newGFp2(pool).Sub(t4, j)
  112. c.x.Sub(t6, t)
  113. t.Sub(v, c.x) // t7
  114. t4.Mul(s1, j, pool) // t8
  115. t6.Add(t4, t4) // t9
  116. t4.Mul(r, t, pool) // t10
  117. c.y.Sub(t4, t6)
  118. t.Add(a.z, b.z) // t11
  119. t4.Square(t, pool) // t12
  120. t.Sub(t4, z1z1) // t13
  121. t4.Sub(t, z2z2) // t14
  122. c.z.Mul(t4, h, pool)
  123. z1z1.Put(pool)
  124. z2z2.Put(pool)
  125. u1.Put(pool)
  126. u2.Put(pool)
  127. t.Put(pool)
  128. s1.Put(pool)
  129. s2.Put(pool)
  130. h.Put(pool)
  131. i.Put(pool)
  132. j.Put(pool)
  133. r.Put(pool)
  134. v.Put(pool)
  135. t4.Put(pool)
  136. t6.Put(pool)
  137. }
  138. func (c *twistPoint) Double(a *twistPoint, pool *bnPool) {
  139. // See http://hyperelliptic.org/EFD/g1p/auto-code/shortw/jacobian-0/doubling/dbl-2009-l.op3
  140. A := newGFp2(pool).Square(a.x, pool)
  141. B := newGFp2(pool).Square(a.y, pool)
  142. C := newGFp2(pool).Square(B, pool)
  143. t := newGFp2(pool).Add(a.x, B)
  144. t2 := newGFp2(pool).Square(t, pool)
  145. t.Sub(t2, A)
  146. t2.Sub(t, C)
  147. d := newGFp2(pool).Add(t2, t2)
  148. t.Add(A, A)
  149. e := newGFp2(pool).Add(t, A)
  150. f := newGFp2(pool).Square(e, pool)
  151. t.Add(d, d)
  152. c.x.Sub(f, t)
  153. t.Add(C, C)
  154. t2.Add(t, t)
  155. t.Add(t2, t2)
  156. c.y.Sub(d, c.x)
  157. t2.Mul(e, c.y, pool)
  158. c.y.Sub(t2, t)
  159. t.Mul(a.y, a.z, pool)
  160. c.z.Add(t, t)
  161. A.Put(pool)
  162. B.Put(pool)
  163. C.Put(pool)
  164. t.Put(pool)
  165. t2.Put(pool)
  166. d.Put(pool)
  167. e.Put(pool)
  168. f.Put(pool)
  169. }
  170. func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoint {
  171. sum := newTwistPoint(pool)
  172. sum.SetInfinity()
  173. t := newTwistPoint(pool)
  174. for i := scalar.BitLen(); i >= 0; i-- {
  175. t.Double(sum, pool)
  176. if scalar.Bit(i) != 0 {
  177. sum.Add(t, a, pool)
  178. } else {
  179. sum.Set(t)
  180. }
  181. }
  182. c.Set(sum)
  183. sum.Put(pool)
  184. t.Put(pool)
  185. return c
  186. }
  187. // MakeAffine converts c to affine form and returns c. If c is ∞, then it sets
  188. // c to 0 : 1 : 0.
  189. func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint {
  190. if c.z.IsOne() {
  191. return c
  192. }
  193. if c.IsInfinity() {
  194. c.x.SetZero()
  195. c.y.SetOne()
  196. c.z.SetZero()
  197. c.t.SetZero()
  198. return c
  199. }
  200. zInv := newGFp2(pool).Invert(c.z, pool)
  201. t := newGFp2(pool).Mul(c.y, zInv, pool)
  202. zInv2 := newGFp2(pool).Square(zInv, pool)
  203. c.y.Mul(t, zInv2, pool)
  204. t.Mul(c.x, zInv2, pool)
  205. c.x.Set(t)
  206. c.z.SetOne()
  207. c.t.SetOne()
  208. zInv.Put(pool)
  209. t.Put(pool)
  210. zInv2.Put(pool)
  211. return c
  212. }
  213. func (c *twistPoint) Negative(a *twistPoint, pool *bnPool) {
  214. c.x.Set(a.x)
  215. c.y.SetZero()
  216. c.y.Sub(c.y, a.y)
  217. c.z.Set(a.z)
  218. c.t.SetZero()
  219. }