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.

417 lines
11 KiB

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