You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

187 lines
5.6 KiB

  1. ## Bn128
  2. [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/bn128?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/bn128) bn128
  3. Implementation of the bn128 pairing in Go.
  4. Implementation followng the information and the implementations from:
  5. - `Multiplication and Squaring on Pairing-Friendly
  6. Fields`, Augusto Jun Devegili, Colm Ó hÉigeartaigh, Michael Scott, and Ricardo Dahab https://pdfs.semanticscholar.org/3e01/de88d7428076b2547b60072088507d881bf1.pdf
  7. - `Optimal Pairings`, Frederik Vercauteren https://www.cosic.esat.kuleuven.be/bcrypt/optimal.pdf , https://eprint.iacr.org/2008/096.pdf
  8. - `Double-and-Add with Relative Jacobian
  9. Coordinates`, Björn Fay https://eprint.iacr.org/2014/1014.pdf
  10. - `Fast and Regular Algorithms for Scalar Multiplication
  11. over Elliptic Curves`, Matthieu Rivain https://eprint.iacr.org/2011/338.pdf
  12. - `High-Speed Software Implementation of the Optimal Ate Pairing over Barreto–Naehrig Curves`, Jean-Luc Beuchat, Jorge E. González-Díaz, Shigeo Mitsunari, Eiji Okamoto, Francisco Rodríguez-Henríquez, and Tadanori Teruya https://eprint.iacr.org/2010/354.pdf
  13. - `New software speed records for cryptographic pairings`, Michael Naehrig, Ruben Niederhagen, Peter Schwabe https://cryptojedi.org/papers/dclxvi-20100714.pdf
  14. - `Implementing Cryptographic Pairings over Barreto-Naehrig Curves`, Augusto Jun Devegili, Michael Scott, Ricardo Dahab https://eprint.iacr.org/2007/390.pdf
  15. - https://github.com/zcash/zcash/tree/master/src/snark
  16. - https://github.com/iden3/snarkjs
  17. - https://github.com/ethereum/py_ecc/tree/master/py_ecc/bn128
  18. - [x] Fq, Fq2, Fq6, Fq12 operations
  19. - [x] G1, G2 operations
  20. - [x] preparePairing
  21. - [x] PreComupteG1, PreComupteG2
  22. - [x] DoubleStep, AddStep
  23. - [x] MillerLoop
  24. - [x] Pairing
  25. ### Installation
  26. ```
  27. go get github.com/arnaucube/bn128
  28. ```
  29. #### Usage
  30. - Pairing
  31. ```go
  32. bn128, err := NewBn128()
  33. assert.Nil(t, err)
  34. big25 := big.NewInt(int64(25))
  35. big30 := big.NewInt(int64(30))
  36. g1a := bn128.G1.MulScalar(bn128.G1.G, big25)
  37. g2a := bn128.G2.MulScalar(bn128.G2.G, big30)
  38. g1b := bn128.G1.MulScalar(bn128.G1.G, big30)
  39. g2b := bn128.G2.MulScalar(bn128.G2.G, big25)
  40. pA, err := bn128.Pairing(g1a, g2a)
  41. assert.Nil(t, err)
  42. pB, err := bn128.Pairing(g1b, g2b)
  43. assert.Nil(t, err)
  44. assert.True(t, bn128.Fq12.Equal(pA, pB))
  45. ```
  46. #### Test
  47. ```
  48. go test -v
  49. ```
  50. ##### Internal operations more deeply
  51. First let's assume that we have these three basic functions to convert integer compositions to big integer compositions:
  52. ```go
  53. func iToBig(a int) *big.Int {
  54. return big.NewInt(int64(a))
  55. }
  56. func iiToBig(a, b int) [2]*big.Int {
  57. return [2]*big.Int{iToBig(a), iToBig(b)}
  58. }
  59. func iiiToBig(a, b int) [2]*big.Int {
  60. return [2]*big.Int{iToBig(a), iToBig(b)}
  61. }
  62. ```
  63. - Finite Fields (1, 2, 6, 12) operations
  64. ```go
  65. // new finite field of order 1
  66. fq1 := NewFq(iToBig(7))
  67. // basic operations of finite field 1
  68. res := fq1.Add(iToBig(4), iToBig(4))
  69. res = fq1.Double(iToBig(5))
  70. res = fq1.Sub(iToBig(5), iToBig(7))
  71. res = fq1.Neg(iToBig(5))
  72. res = fq1.Mul(iToBig(5), iToBig(11))
  73. res = fq1.Inverse(iToBig(4))
  74. res = fq1.Square(iToBig(5))
  75. // new finite field of order 2
  76. nonResidueFq2str := "-1" // i/j
  77. nonResidueFq2, ok := new(big.Int).SetString(nonResidueFq2str, 10)
  78. fq2 := Fq2{fq1, nonResidueFq2}
  79. nonResidueFq6 := iiToBig(9, 1)
  80. // basic operations of finite field of order 2
  81. res := fq2.Add(iiToBig(4, 4), iiToBig(3, 4))
  82. res = fq2.Double(iiToBig(5, 3))
  83. res = fq2.Sub(iiToBig(5, 3), iiToBig(7, 2))
  84. res = fq2.Neg(iiToBig(4, 4))
  85. res = fq2.Mul(iiToBig(4, 4), iiToBig(3, 4))
  86. res = fq2.Inverse(iiToBig(4, 4))
  87. res = fq2.Div(iiToBig(4, 4), iiToBig(3, 4))
  88. res = fq2.Square(iiToBig(4, 4))
  89. // new finite field of order 6
  90. nonResidueFq6 := iiToBig(9, 1) // TODO
  91. fq6 := Fq6{fq2, nonResidueFq6}
  92. // define two new values of Finite Field 6, in order to be able to perform the operations
  93. a := [3][2]*big.Int{
  94. iiToBig(1, 2),
  95. iiToBig(3, 4),
  96. iiToBig(5, 6)}
  97. b := [3][2]*big.Int{
  98. iiToBig(12, 11),
  99. iiToBig(10, 9),
  100. iiToBig(8, 7)}
  101. // basic operations of finite field order 6
  102. res := fq6.Add(a, b)
  103. res = fq6.Sub(a, b)
  104. res = fq6.Mul(a, b)
  105. divRes := fq6.Div(mulRes, b)
  106. // new finite field of order 12
  107. q, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10) // i
  108. if !ok {
  109. fmt.Println("error parsing string to big integer")
  110. }
  111. fq1 := NewFq(q)
  112. nonResidueFq2, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10) // i
  113. assert.True(t, ok)
  114. nonResidueFq6 := iiToBig(9, 1)
  115. fq2 := Fq2{fq1, nonResidueFq2}
  116. fq6 := Fq6{fq2, nonResidueFq6}
  117. fq12 := Fq12{fq6, fq2, nonResidueFq6}
  118. ```
  119. - G1 operations
  120. ```go
  121. bn128, err := NewBn128()
  122. assert.Nil(t, err)
  123. r1 := big.NewInt(int64(33))
  124. r2 := big.NewInt(int64(44))
  125. gr1 := bn128.G1.MulScalar(bn128.G1.G, bn128.Fq1.Copy(r1))
  126. gr2 := bn128.G1.MulScalar(bn128.G1.G, bn128.Fq1.Copy(r2))
  127. grsum1 := bn128.G1.Add(gr1, gr2)
  128. r1r2 := bn128.Fq1.Add(r1, r2)
  129. grsum2 := bn128.G1.MulScalar(bn128.G1.G, r1r2)
  130. a := bn128.G1.Affine(grsum1)
  131. b := bn128.G1.Affine(grsum2)
  132. assert.Equal(t, a, b)
  133. assert.Equal(t, "0x2f978c0ab89ebaa576866706b14787f360c4d6c3869efe5a72f7c3651a72ff00", utils.BytesToHex(a[0].Bytes()))
  134. assert.Equal(t, "0x12e4ba7f0edca8b4fa668fe153aebd908d322dc26ad964d4cd314795844b62b2", utils.BytesToHex(a[1].Bytes()))
  135. ```
  136. - G2 operations
  137. ```go
  138. bn128, err := NewBn128()
  139. assert.Nil(t, err)
  140. r1 := big.NewInt(int64(33))
  141. r2 := big.NewInt(int64(44))
  142. gr1 := bn128.G2.MulScalar(bn128.G2.G, bn128.Fq1.Copy(r1))
  143. gr2 := bn128.G2.MulScalar(bn128.G2.G, bn128.Fq1.Copy(r2))
  144. grsum1 := bn128.G2.Add(gr1, gr2)
  145. r1r2 := bn128.Fq1.Add(r1, r2)
  146. grsum2 := bn128.G2.MulScalar(bn128.G2.G, r1r2)
  147. a := bn128.G2.Affine(grsum1)
  148. b := bn128.G2.Affine(grsum2)
  149. assert.Equal(t, a, b)
  150. ```