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