g2.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. // Copyright 2020 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package bls12381
  17. import (
  18. "errors"
  19. "math"
  20. "math/big"
  21. )
  22. // PointG2 is type for point in G2.
  23. // PointG2 is both used for Affine and Jacobian point representation.
  24. // If z is equal to one the point is considered as in affine form.
  25. type PointG2 [3]fe2
  26. // Set copies valeus of one point to another.
  27. func (p *PointG2) Set(p2 *PointG2) *PointG2 {
  28. p[0].set(&p2[0])
  29. p[1].set(&p2[1])
  30. p[2].set(&p2[2])
  31. return p
  32. }
  33. // Zero returns G2 point in point at infinity representation
  34. func (p *PointG2) Zero() *PointG2 {
  35. p[0].zero()
  36. p[1].one()
  37. p[2].zero()
  38. return p
  39. }
  40. type tempG2 struct {
  41. t [9]*fe2
  42. }
  43. // G2 is struct for G2 group.
  44. type G2 struct {
  45. f *fp2
  46. tempG2
  47. }
  48. // NewG2 constructs a new G2 instance.
  49. func NewG2() *G2 {
  50. return newG2(nil)
  51. }
  52. func newG2(f *fp2) *G2 {
  53. if f == nil {
  54. f = newFp2()
  55. }
  56. t := newTempG2()
  57. return &G2{f, t}
  58. }
  59. func newTempG2() tempG2 {
  60. t := [9]*fe2{}
  61. for i := 0; i < 9; i++ {
  62. t[i] = &fe2{}
  63. }
  64. return tempG2{t}
  65. }
  66. // Q returns group order in big.Int.
  67. func (g *G2) Q() *big.Int {
  68. return new(big.Int).Set(q)
  69. }
  70. func (g *G2) fromBytesUnchecked(in []byte) (*PointG2, error) {
  71. p0, err := g.f.fromBytes(in[:96])
  72. if err != nil {
  73. return nil, err
  74. }
  75. p1, err := g.f.fromBytes(in[96:])
  76. if err != nil {
  77. return nil, err
  78. }
  79. p2 := new(fe2).one()
  80. return &PointG2{*p0, *p1, *p2}, nil
  81. }
  82. // FromBytes constructs a new point given uncompressed byte input.
  83. // FromBytes does not take zcash flags into account.
  84. // Byte input expected to be larger than 96 bytes.
  85. // First 192 bytes should be concatenation of x and y values
  86. // Point (0, 0) is considered as infinity.
  87. func (g *G2) FromBytes(in []byte) (*PointG2, error) {
  88. if len(in) != 192 {
  89. return nil, errors.New("input string should be equal or larger than 192")
  90. }
  91. p0, err := g.f.fromBytes(in[:96])
  92. if err != nil {
  93. return nil, err
  94. }
  95. p1, err := g.f.fromBytes(in[96:])
  96. if err != nil {
  97. return nil, err
  98. }
  99. // check if given input points to infinity
  100. if p0.isZero() && p1.isZero() {
  101. return g.Zero(), nil
  102. }
  103. p2 := new(fe2).one()
  104. p := &PointG2{*p0, *p1, *p2}
  105. if !g.IsOnCurve(p) {
  106. return nil, errors.New("point is not on curve")
  107. }
  108. return p, nil
  109. }
  110. // DecodePoint given encoded (x, y) coordinates in 256 bytes returns a valid G1 Point.
  111. func (g *G2) DecodePoint(in []byte) (*PointG2, error) {
  112. if len(in) != 256 {
  113. return nil, errors.New("invalid g2 point length")
  114. }
  115. pointBytes := make([]byte, 192)
  116. x0Bytes, err := decodeFieldElement(in[:64])
  117. if err != nil {
  118. return nil, err
  119. }
  120. x1Bytes, err := decodeFieldElement(in[64:128])
  121. if err != nil {
  122. return nil, err
  123. }
  124. y0Bytes, err := decodeFieldElement(in[128:192])
  125. if err != nil {
  126. return nil, err
  127. }
  128. y1Bytes, err := decodeFieldElement(in[192:])
  129. if err != nil {
  130. return nil, err
  131. }
  132. copy(pointBytes[:48], x1Bytes)
  133. copy(pointBytes[48:96], x0Bytes)
  134. copy(pointBytes[96:144], y1Bytes)
  135. copy(pointBytes[144:192], y0Bytes)
  136. return g.FromBytes(pointBytes)
  137. }
  138. // ToBytes serializes a point into bytes in uncompressed form,
  139. // does not take zcash flags into account,
  140. // returns (0, 0) if point is infinity.
  141. func (g *G2) ToBytes(p *PointG2) []byte {
  142. out := make([]byte, 192)
  143. if g.IsZero(p) {
  144. return out
  145. }
  146. g.Affine(p)
  147. copy(out[:96], g.f.toBytes(&p[0]))
  148. copy(out[96:], g.f.toBytes(&p[1]))
  149. return out
  150. }
  151. // EncodePoint encodes a point into 256 bytes.
  152. func (g *G2) EncodePoint(p *PointG2) []byte {
  153. // outRaw is 96 bytes
  154. outRaw := g.ToBytes(p)
  155. out := make([]byte, 256)
  156. // encode x
  157. copy(out[16:16+48], outRaw[48:96])
  158. copy(out[80:80+48], outRaw[:48])
  159. // encode y
  160. copy(out[144:144+48], outRaw[144:])
  161. copy(out[208:208+48], outRaw[96:144])
  162. return out
  163. }
  164. // New creates a new G2 Point which is equal to zero in other words point at infinity.
  165. func (g *G2) New() *PointG2 {
  166. return new(PointG2).Zero()
  167. }
  168. // Zero returns a new G2 Point which is equal to point at infinity.
  169. func (g *G2) Zero() *PointG2 {
  170. return new(PointG2).Zero()
  171. }
  172. // One returns a new G2 Point which is equal to generator point.
  173. func (g *G2) One() *PointG2 {
  174. p := &PointG2{}
  175. return p.Set(&g2One)
  176. }
  177. // IsZero returns true if given point is equal to zero.
  178. func (g *G2) IsZero(p *PointG2) bool {
  179. return p[2].isZero()
  180. }
  181. // Equal checks if given two G2 point is equal in their affine form.
  182. func (g *G2) Equal(p1, p2 *PointG2) bool {
  183. if g.IsZero(p1) {
  184. return g.IsZero(p2)
  185. }
  186. if g.IsZero(p2) {
  187. return g.IsZero(p1)
  188. }
  189. t := g.t
  190. g.f.square(t[0], &p1[2])
  191. g.f.square(t[1], &p2[2])
  192. g.f.mul(t[2], t[0], &p2[0])
  193. g.f.mul(t[3], t[1], &p1[0])
  194. g.f.mul(t[0], t[0], &p1[2])
  195. g.f.mul(t[1], t[1], &p2[2])
  196. g.f.mul(t[1], t[1], &p1[1])
  197. g.f.mul(t[0], t[0], &p2[1])
  198. return t[0].equal(t[1]) && t[2].equal(t[3])
  199. }
  200. // InCorrectSubgroup checks whether given point is in correct subgroup.
  201. func (g *G2) InCorrectSubgroup(p *PointG2) bool {
  202. tmp := &PointG2{}
  203. g.MulScalar(tmp, p, q)
  204. return g.IsZero(tmp)
  205. }
  206. // IsOnCurve checks a G2 point is on curve.
  207. func (g *G2) IsOnCurve(p *PointG2) bool {
  208. if g.IsZero(p) {
  209. return true
  210. }
  211. t := g.t
  212. g.f.square(t[0], &p[1])
  213. g.f.square(t[1], &p[0])
  214. g.f.mul(t[1], t[1], &p[0])
  215. g.f.square(t[2], &p[2])
  216. g.f.square(t[3], t[2])
  217. g.f.mul(t[2], t[2], t[3])
  218. g.f.mul(t[2], b2, t[2])
  219. g.f.add(t[1], t[1], t[2])
  220. return t[0].equal(t[1])
  221. }
  222. // IsAffine checks a G2 point whether it is in affine form.
  223. func (g *G2) IsAffine(p *PointG2) bool {
  224. return p[2].isOne()
  225. }
  226. // Affine calculates affine form of given G2 point.
  227. func (g *G2) Affine(p *PointG2) *PointG2 {
  228. if g.IsZero(p) {
  229. return p
  230. }
  231. if !g.IsAffine(p) {
  232. t := g.t
  233. g.f.inverse(t[0], &p[2])
  234. g.f.square(t[1], t[0])
  235. g.f.mul(&p[0], &p[0], t[1])
  236. g.f.mul(t[0], t[0], t[1])
  237. g.f.mul(&p[1], &p[1], t[0])
  238. p[2].one()
  239. }
  240. return p
  241. }
  242. // Add adds two G2 points p1, p2 and assigns the result to point at first argument.
  243. func (g *G2) Add(r, p1, p2 *PointG2) *PointG2 {
  244. // http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#addition-add-2007-bl
  245. if g.IsZero(p1) {
  246. return r.Set(p2)
  247. }
  248. if g.IsZero(p2) {
  249. return r.Set(p1)
  250. }
  251. t := g.t
  252. g.f.square(t[7], &p1[2])
  253. g.f.mul(t[1], &p2[0], t[7])
  254. g.f.mul(t[2], &p1[2], t[7])
  255. g.f.mul(t[0], &p2[1], t[2])
  256. g.f.square(t[8], &p2[2])
  257. g.f.mul(t[3], &p1[0], t[8])
  258. g.f.mul(t[4], &p2[2], t[8])
  259. g.f.mul(t[2], &p1[1], t[4])
  260. if t[1].equal(t[3]) {
  261. if t[0].equal(t[2]) {
  262. return g.Double(r, p1)
  263. } else {
  264. return r.Zero()
  265. }
  266. }
  267. g.f.sub(t[1], t[1], t[3])
  268. g.f.double(t[4], t[1])
  269. g.f.square(t[4], t[4])
  270. g.f.mul(t[5], t[1], t[4])
  271. g.f.sub(t[0], t[0], t[2])
  272. g.f.double(t[0], t[0])
  273. g.f.square(t[6], t[0])
  274. g.f.sub(t[6], t[6], t[5])
  275. g.f.mul(t[3], t[3], t[4])
  276. g.f.double(t[4], t[3])
  277. g.f.sub(&r[0], t[6], t[4])
  278. g.f.sub(t[4], t[3], &r[0])
  279. g.f.mul(t[6], t[2], t[5])
  280. g.f.double(t[6], t[6])
  281. g.f.mul(t[0], t[0], t[4])
  282. g.f.sub(&r[1], t[0], t[6])
  283. g.f.add(t[0], &p1[2], &p2[2])
  284. g.f.square(t[0], t[0])
  285. g.f.sub(t[0], t[0], t[7])
  286. g.f.sub(t[0], t[0], t[8])
  287. g.f.mul(&r[2], t[0], t[1])
  288. return r
  289. }
  290. // Double doubles a G2 point p and assigns the result to the point at first argument.
  291. func (g *G2) Double(r, p *PointG2) *PointG2 {
  292. // http://www.hyperelliptic.org/EFD/gp/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
  293. if g.IsZero(p) {
  294. return r.Set(p)
  295. }
  296. t := g.t
  297. g.f.square(t[0], &p[0])
  298. g.f.square(t[1], &p[1])
  299. g.f.square(t[2], t[1])
  300. g.f.add(t[1], &p[0], t[1])
  301. g.f.square(t[1], t[1])
  302. g.f.sub(t[1], t[1], t[0])
  303. g.f.sub(t[1], t[1], t[2])
  304. g.f.double(t[1], t[1])
  305. g.f.double(t[3], t[0])
  306. g.f.add(t[0], t[3], t[0])
  307. g.f.square(t[4], t[0])
  308. g.f.double(t[3], t[1])
  309. g.f.sub(&r[0], t[4], t[3])
  310. g.f.sub(t[1], t[1], &r[0])
  311. g.f.double(t[2], t[2])
  312. g.f.double(t[2], t[2])
  313. g.f.double(t[2], t[2])
  314. g.f.mul(t[0], t[0], t[1])
  315. g.f.sub(t[1], t[0], t[2])
  316. g.f.mul(t[0], &p[1], &p[2])
  317. r[1].set(t[1])
  318. g.f.double(&r[2], t[0])
  319. return r
  320. }
  321. // Neg negates a G2 point p and assigns the result to the point at first argument.
  322. func (g *G2) Neg(r, p *PointG2) *PointG2 {
  323. r[0].set(&p[0])
  324. g.f.neg(&r[1], &p[1])
  325. r[2].set(&p[2])
  326. return r
  327. }
  328. // Sub subtracts two G2 points p1, p2 and assigns the result to point at first argument.
  329. func (g *G2) Sub(c, a, b *PointG2) *PointG2 {
  330. d := &PointG2{}
  331. g.Neg(d, b)
  332. g.Add(c, a, d)
  333. return c
  334. }
  335. // MulScalar multiplies a point by given scalar value in big.Int and assigns the result to point at first argument.
  336. func (g *G2) MulScalar(c, p *PointG2, e *big.Int) *PointG2 {
  337. q, n := &PointG2{}, &PointG2{}
  338. n.Set(p)
  339. l := e.BitLen()
  340. for i := 0; i < l; i++ {
  341. if e.Bit(i) == 1 {
  342. g.Add(q, q, n)
  343. }
  344. g.Double(n, n)
  345. }
  346. return c.Set(q)
  347. }
  348. // ClearCofactor maps given a G2 point to correct subgroup
  349. func (g *G2) ClearCofactor(p *PointG2) {
  350. g.MulScalar(p, p, cofactorEFFG2)
  351. }
  352. // MultiExp calculates multi exponentiation. Given pairs of G2 point and scalar values
  353. // (P_0, e_0), (P_1, e_1), ... (P_n, e_n) calculates r = e_0 * P_0 + e_1 * P_1 + ... + e_n * P_n
  354. // Length of points and scalars are expected to be equal, otherwise an error is returned.
  355. // Result is assigned to point at first argument.
  356. func (g *G2) MultiExp(r *PointG2, points []*PointG2, powers []*big.Int) (*PointG2, error) {
  357. if len(points) != len(powers) {
  358. return nil, errors.New("point and scalar vectors should be in same length")
  359. }
  360. var c uint32 = 3
  361. if len(powers) >= 32 {
  362. c = uint32(math.Ceil(math.Log10(float64(len(powers)))))
  363. }
  364. bucketSize, numBits := (1<<c)-1, uint32(g.Q().BitLen())
  365. windows := make([]*PointG2, numBits/c+1)
  366. bucket := make([]*PointG2, bucketSize)
  367. acc, sum := g.New(), g.New()
  368. for i := 0; i < bucketSize; i++ {
  369. bucket[i] = g.New()
  370. }
  371. mask := (uint64(1) << c) - 1
  372. j := 0
  373. var cur uint32
  374. for cur <= numBits {
  375. acc.Zero()
  376. bucket = make([]*PointG2, (1<<c)-1)
  377. for i := 0; i < len(bucket); i++ {
  378. bucket[i] = g.New()
  379. }
  380. for i := 0; i < len(powers); i++ {
  381. s0 := powers[i].Uint64()
  382. index := uint(s0 & mask)
  383. if index != 0 {
  384. g.Add(bucket[index-1], bucket[index-1], points[i])
  385. }
  386. powers[i] = new(big.Int).Rsh(powers[i], uint(c))
  387. }
  388. sum.Zero()
  389. for i := len(bucket) - 1; i >= 0; i-- {
  390. g.Add(sum, sum, bucket[i])
  391. g.Add(acc, acc, sum)
  392. }
  393. windows[j] = g.New()
  394. windows[j].Set(acc)
  395. j++
  396. cur += c
  397. }
  398. acc.Zero()
  399. for i := len(windows) - 1; i >= 0; i-- {
  400. for j := uint32(0); j < c; j++ {
  401. g.Double(acc, acc)
  402. }
  403. g.Add(acc, acc, windows[i])
  404. }
  405. return r.Set(acc), nil
  406. }
  407. // MapToCurve given a byte slice returns a valid G2 point.
  408. // This mapping function implements the Simplified Shallue-van de Woestijne-Ulas method.
  409. // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-05#section-6.6.2
  410. // Input byte slice should be a valid field element, otherwise an error is returned.
  411. func (g *G2) MapToCurve(in []byte) (*PointG2, error) {
  412. fp2 := g.f
  413. u, err := fp2.fromBytes(in)
  414. if err != nil {
  415. return nil, err
  416. }
  417. x, y := swuMapG2(fp2, u)
  418. isogenyMapG2(fp2, x, y)
  419. z := new(fe2).one()
  420. q := &PointG2{*x, *y, *z}
  421. g.ClearCofactor(q)
  422. return g.Affine(q), nil
  423. }