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.

421 lines
11 KiB

  1. package bn128
  2. import (
  3. "errors"
  4. "math/big"
  5. "github.com/arnaucube/go-snark-study/fields"
  6. )
  7. // Bn128 is the data structure of the BN128
  8. type Bn128 struct {
  9. Q *big.Int
  10. R *big.Int
  11. Gg1 [2]*big.Int
  12. Gg2 [2][2]*big.Int
  13. NonResidueFq2 *big.Int
  14. NonResidueFq6 [2]*big.Int
  15. Fq1 fields.Fq
  16. Fq2 fields.Fq2
  17. Fq6 fields.Fq6
  18. Fq12 fields.Fq12
  19. G1 G1
  20. G2 G2
  21. LoopCount *big.Int
  22. LoopCountNeg bool
  23. TwoInv *big.Int
  24. CoefB *big.Int
  25. TwistCoefB [2]*big.Int
  26. Twist [2]*big.Int
  27. FrobeniusCoeffsC11 *big.Int
  28. TwistMulByQX [2]*big.Int
  29. TwistMulByQY [2]*big.Int
  30. FinalExp *big.Int
  31. }
  32. // NewBn128 returns the BN128
  33. func NewBn128() (Bn128, error) {
  34. var b Bn128
  35. q, ok := new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208583", 10)
  36. if !ok {
  37. return b, errors.New("err with q")
  38. }
  39. b.Q = q
  40. r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
  41. if !ok {
  42. return b, errors.New("err with r")
  43. }
  44. b.R = r
  45. b.Gg1 = [2]*big.Int{
  46. big.NewInt(int64(1)),
  47. big.NewInt(int64(2)),
  48. }
  49. g2_00, ok := new(big.Int).SetString("10857046999023057135944570762232829481370756359578518086990519993285655852781", 10)
  50. if !ok {
  51. return b, errors.New("err with g2_00")
  52. }
  53. g2_01, ok := new(big.Int).SetString("11559732032986387107991004021392285783925812861821192530917403151452391805634", 10)
  54. if !ok {
  55. return b, errors.New("err with g2_00")
  56. }
  57. g2_10, ok := new(big.Int).SetString("8495653923123431417604973247489272438418190587263600148770280649306958101930", 10)
  58. if !ok {
  59. return b, errors.New("err with g2_00")
  60. }
  61. g2_11, ok := new(big.Int).SetString("4082367875863433681332203403145435568316851327593401208105741076214120093531", 10)
  62. if !ok {
  63. return b, errors.New("err with g2_00")
  64. }
  65. b.Gg2 = [2][2]*big.Int{
  66. [2]*big.Int{
  67. g2_00,
  68. g2_01,
  69. },
  70. [2]*big.Int{
  71. g2_10,
  72. g2_11,
  73. },
  74. }
  75. b.Fq1 = fields.NewFq(q)
  76. b.NonResidueFq2, ok = new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10) // i
  77. if !ok {
  78. return b, errors.New("err with nonResidueFq2")
  79. }
  80. b.NonResidueFq6 = [2]*big.Int{
  81. big.NewInt(int64(9)),
  82. big.NewInt(int64(1)),
  83. }
  84. b.Fq2 = fields.NewFq2(b.Fq1, b.NonResidueFq2)
  85. b.Fq6 = fields.NewFq6(b.Fq2, b.NonResidueFq6)
  86. b.Fq12 = fields.NewFq12(b.Fq6, b.Fq2, b.NonResidueFq6)
  87. b.G1 = NewG1(b.Fq1, b.Gg1)
  88. b.G2 = NewG2(b.Fq2, b.Gg2)
  89. err := b.preparePairing()
  90. if err != nil {
  91. return b, err
  92. }
  93. return b, nil
  94. }
  95. // NewFqR returns a new Finite Field over R
  96. func NewFqR() (fields.Fq, error) {
  97. r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
  98. if !ok {
  99. return fields.Fq{}, errors.New("err parsing R")
  100. }
  101. fqR := fields.NewFq(r)
  102. return fqR, nil
  103. }
  104. func (bn128 *Bn128) preparePairing() error {
  105. var ok bool
  106. bn128.LoopCount, ok = new(big.Int).SetString("29793968203157093288", 10)
  107. if !ok {
  108. return errors.New("err with LoopCount from string")
  109. }
  110. bn128.LoopCountNeg = false
  111. bn128.TwoInv = bn128.Fq1.Inverse(big.NewInt(int64(2)))
  112. bn128.CoefB = big.NewInt(int64(3))
  113. bn128.Twist = [2]*big.Int{
  114. big.NewInt(int64(9)),
  115. big.NewInt(int64(1)),
  116. }
  117. bn128.TwistCoefB = bn128.Fq2.MulScalar(bn128.Fq2.Inverse(bn128.Twist), bn128.CoefB)
  118. bn128.FrobeniusCoeffsC11, ok = new(big.Int).SetString("21888242871839275222246405745257275088696311157297823662689037894645226208582", 10)
  119. if !ok {
  120. return errors.New("error parsing frobeniusCoeffsC11")
  121. }
  122. a, ok := new(big.Int).SetString("21575463638280843010398324269430826099269044274347216827212613867836435027261", 10)
  123. if !ok {
  124. return errors.New("error parsing a")
  125. }
  126. b, ok := new(big.Int).SetString("10307601595873709700152284273816112264069230130616436755625194854815875713954", 10)
  127. if !ok {
  128. return errors.New("error parsing b")
  129. }
  130. bn128.TwistMulByQX = [2]*big.Int{
  131. a,
  132. b,
  133. }
  134. a, ok = new(big.Int).SetString("2821565182194536844548159561693502659359617185244120367078079554186484126554", 10)
  135. if !ok {
  136. return errors.New("error parsing a")
  137. }
  138. b, ok = new(big.Int).SetString("3505843767911556378687030309984248845540243509899259641013678093033130930403", 10)
  139. if !ok {
  140. return errors.New("error parsing b")
  141. }
  142. bn128.TwistMulByQY = [2]*big.Int{
  143. a,
  144. b,
  145. }
  146. bn128.FinalExp, ok = new(big.Int).SetString("552484233613224096312617126783173147097382103762957654188882734314196910839907541213974502761540629817009608548654680343627701153829446747810907373256841551006201639677726139946029199968412598804882391702273019083653272047566316584365559776493027495458238373902875937659943504873220554161550525926302303331747463515644711876653177129578303191095900909191624817826566688241804408081892785725967931714097716709526092261278071952560171111444072049229123565057483750161460024353346284167282452756217662335528813519139808291170539072125381230815729071544861602750936964829313608137325426383735122175229541155376346436093930287402089517426973178917569713384748081827255472576937471496195752727188261435633271238710131736096299798168852925540549342330775279877006784354801422249722573783561685179618816480037695005515426162362431072245638324744480", 10)
  147. if !ok {
  148. return errors.New("error parsing finalExp")
  149. }
  150. return nil
  151. }
  152. // Pairing calculates the BN128 Pairing of two given values
  153. func (bn128 Bn128) Pairing(p1 [3]*big.Int, p2 [3][2]*big.Int) [2][3][2]*big.Int {
  154. pre1 := bn128.preComputeG1(p1)
  155. pre2 := bn128.preComputeG2(p2)
  156. r1 := bn128.MillerLoop(pre1, pre2)
  157. res := bn128.finalExponentiation(r1)
  158. return res
  159. }
  160. type AteG1Precomp struct {
  161. Px *big.Int
  162. Py *big.Int
  163. }
  164. func (bn128 Bn128) preComputeG1(p [3]*big.Int) AteG1Precomp {
  165. pCopy := bn128.G1.Affine(p)
  166. res := AteG1Precomp{
  167. Px: pCopy[0],
  168. Py: pCopy[1],
  169. }
  170. return res
  171. }
  172. type EllCoeffs struct {
  173. Ell0 [2]*big.Int
  174. EllVW [2]*big.Int
  175. EllVV [2]*big.Int
  176. }
  177. type AteG2Precomp struct {
  178. Qx [2]*big.Int
  179. Qy [2]*big.Int
  180. Coeffs []EllCoeffs
  181. }
  182. func (bn128 Bn128) preComputeG2(p [3][2]*big.Int) AteG2Precomp {
  183. qCopy := bn128.G2.Affine(p)
  184. res := AteG2Precomp{
  185. qCopy[0],
  186. qCopy[1],
  187. []EllCoeffs{},
  188. }
  189. r := [3][2]*big.Int{
  190. bn128.Fq2.Copy(qCopy[0]),
  191. bn128.Fq2.Copy(qCopy[1]),
  192. bn128.Fq2.One(),
  193. }
  194. var c EllCoeffs
  195. for i := bn128.LoopCount.BitLen() - 2; i >= 0; i-- {
  196. bit := bn128.LoopCount.Bit(i)
  197. c, r = bn128.doublingStep(r)
  198. res.Coeffs = append(res.Coeffs, c)
  199. if bit == 1 {
  200. c, r = bn128.mixedAdditionStep(qCopy, r)
  201. res.Coeffs = append(res.Coeffs, c)
  202. }
  203. }
  204. q1 := bn128.G2.Affine(bn128.g2MulByQ(qCopy))
  205. if !bn128.Fq2.Equal(q1[2], bn128.Fq2.One()) {
  206. // return res, errors.New("q1[2] != Fq2.One")
  207. panic(errors.New("q1[2] != Fq2.One()"))
  208. }
  209. q2 := bn128.G2.Affine(bn128.g2MulByQ(q1))
  210. if !bn128.Fq2.Equal(q2[2], bn128.Fq2.One()) {
  211. // return res, errors.New("q2[2] != Fq2.One")
  212. panic(errors.New("q2[2] != Fq2.One()"))
  213. }
  214. if bn128.LoopCountNeg {
  215. r[1] = bn128.Fq2.Neg(r[1])
  216. }
  217. q2[1] = bn128.Fq2.Neg(q2[1])
  218. c, r = bn128.mixedAdditionStep(q1, r)
  219. res.Coeffs = append(res.Coeffs, c)
  220. c, r = bn128.mixedAdditionStep(q2, r)
  221. res.Coeffs = append(res.Coeffs, c)
  222. return res
  223. }
  224. func (bn128 Bn128) doublingStep(current [3][2]*big.Int) (EllCoeffs, [3][2]*big.Int) {
  225. x := current[0]
  226. y := current[1]
  227. z := current[2]
  228. a := bn128.Fq2.MulScalar(bn128.Fq2.Mul(x, y), bn128.TwoInv)
  229. b := bn128.Fq2.Square(y)
  230. c := bn128.Fq2.Square(z)
  231. d := bn128.Fq2.Add(c, bn128.Fq2.Add(c, c))
  232. e := bn128.Fq2.Mul(bn128.TwistCoefB, d)
  233. f := bn128.Fq2.Add(e, bn128.Fq2.Add(e, e))
  234. g := bn128.Fq2.MulScalar(bn128.Fq2.Add(b, f), bn128.TwoInv)
  235. h := bn128.Fq2.Sub(
  236. bn128.Fq2.Square(bn128.Fq2.Add(y, z)),
  237. bn128.Fq2.Add(b, c))
  238. i := bn128.Fq2.Sub(e, b)
  239. j := bn128.Fq2.Square(x)
  240. eSqr := bn128.Fq2.Square(e)
  241. current[0] = bn128.Fq2.Mul(a, bn128.Fq2.Sub(b, f))
  242. current[1] = bn128.Fq2.Sub(bn128.Fq2.Sub(bn128.Fq2.Square(g), eSqr),
  243. bn128.Fq2.Add(eSqr, eSqr))
  244. current[2] = bn128.Fq2.Mul(b, h)
  245. res := EllCoeffs{
  246. Ell0: bn128.Fq2.Mul(i, bn128.Twist),
  247. EllVW: bn128.Fq2.Neg(h),
  248. EllVV: bn128.Fq2.Add(j, bn128.Fq2.Add(j, j)),
  249. }
  250. return res, current
  251. }
  252. func (bn128 Bn128) mixedAdditionStep(base, current [3][2]*big.Int) (EllCoeffs, [3][2]*big.Int) {
  253. x1 := current[0]
  254. y1 := current[1]
  255. z1 := current[2]
  256. x2 := base[0]
  257. y2 := base[1]
  258. d := bn128.Fq2.Sub(x1, bn128.Fq2.Mul(x2, z1))
  259. e := bn128.Fq2.Sub(y1, bn128.Fq2.Mul(y2, z1))
  260. f := bn128.Fq2.Square(d)
  261. g := bn128.Fq2.Square(e)
  262. h := bn128.Fq2.Mul(d, f)
  263. i := bn128.Fq2.Mul(x1, f)
  264. j := bn128.Fq2.Sub(
  265. bn128.Fq2.Add(h, bn128.Fq2.Mul(z1, g)),
  266. bn128.Fq2.Add(i, i))
  267. current[0] = bn128.Fq2.Mul(d, j)
  268. current[1] = bn128.Fq2.Sub(
  269. bn128.Fq2.Mul(e, bn128.Fq2.Sub(i, j)),
  270. bn128.Fq2.Mul(h, y1))
  271. current[2] = bn128.Fq2.Mul(z1, h)
  272. coef := EllCoeffs{
  273. Ell0: bn128.Fq2.Mul(
  274. bn128.Twist,
  275. bn128.Fq2.Sub(
  276. bn128.Fq2.Mul(e, x2),
  277. bn128.Fq2.Mul(d, y2))),
  278. EllVW: d,
  279. EllVV: bn128.Fq2.Neg(e),
  280. }
  281. return coef, current
  282. }
  283. func (bn128 Bn128) g2MulByQ(p [3][2]*big.Int) [3][2]*big.Int {
  284. fmx := [2]*big.Int{
  285. p[0][0],
  286. bn128.Fq1.Mul(p[0][1], bn128.Fq1.Copy(bn128.FrobeniusCoeffsC11)),
  287. }
  288. fmy := [2]*big.Int{
  289. p[1][0],
  290. bn128.Fq1.Mul(p[1][1], bn128.Fq1.Copy(bn128.FrobeniusCoeffsC11)),
  291. }
  292. fmz := [2]*big.Int{
  293. p[2][0],
  294. bn128.Fq1.Mul(p[2][1], bn128.Fq1.Copy(bn128.FrobeniusCoeffsC11)),
  295. }
  296. return [3][2]*big.Int{
  297. bn128.Fq2.Mul(bn128.TwistMulByQX, fmx),
  298. bn128.Fq2.Mul(bn128.TwistMulByQY, fmy),
  299. fmz,
  300. }
  301. }
  302. func (bn128 Bn128) MillerLoop(pre1 AteG1Precomp, pre2 AteG2Precomp) [2][3][2]*big.Int {
  303. // https://cryptojedi.org/papers/dclxvi-20100714.pdf
  304. // https://eprint.iacr.org/2008/096.pdf
  305. idx := 0
  306. var c EllCoeffs
  307. f := bn128.Fq12.One()
  308. for i := bn128.LoopCount.BitLen() - 2; i >= 0; i-- {
  309. bit := bn128.LoopCount.Bit(i)
  310. c = pre2.Coeffs[idx]
  311. idx++
  312. f = bn128.Fq12.Square(f)
  313. f = bn128.mulBy024(f,
  314. c.Ell0,
  315. bn128.Fq2.MulScalar(c.EllVW, pre1.Py),
  316. bn128.Fq2.MulScalar(c.EllVV, pre1.Px))
  317. if bit == 1 {
  318. c = pre2.Coeffs[idx]
  319. idx++
  320. f = bn128.mulBy024(
  321. f,
  322. c.Ell0,
  323. bn128.Fq2.MulScalar(c.EllVW, pre1.Py),
  324. bn128.Fq2.MulScalar(c.EllVV, pre1.Px))
  325. }
  326. }
  327. if bn128.LoopCountNeg {
  328. f = bn128.Fq12.Inverse(f)
  329. }
  330. c = pre2.Coeffs[idx]
  331. idx++
  332. f = bn128.mulBy024(
  333. f,
  334. c.Ell0,
  335. bn128.Fq2.MulScalar(c.EllVW, pre1.Py),
  336. bn128.Fq2.MulScalar(c.EllVV, pre1.Px))
  337. c = pre2.Coeffs[idx]
  338. idx++
  339. f = bn128.mulBy024(
  340. f,
  341. c.Ell0,
  342. bn128.Fq2.MulScalar(c.EllVW, pre1.Py),
  343. bn128.Fq2.MulScalar(c.EllVV, pre1.Px))
  344. return f
  345. }
  346. func (bn128 Bn128) mulBy024(a [2][3][2]*big.Int, ell0, ellVW, ellVV [2]*big.Int) [2][3][2]*big.Int {
  347. b := [2][3][2]*big.Int{
  348. [3][2]*big.Int{
  349. ell0,
  350. bn128.Fq2.Zero(),
  351. ellVV,
  352. },
  353. [3][2]*big.Int{
  354. bn128.Fq2.Zero(),
  355. ellVW,
  356. bn128.Fq2.Zero(),
  357. },
  358. }
  359. return bn128.Fq12.Mul(a, b)
  360. }
  361. func (bn128 Bn128) finalExponentiation(r [2][3][2]*big.Int) [2][3][2]*big.Int {
  362. res := bn128.Fq12.Exp(r, bn128.FinalExp)
  363. return res
  364. }