go-iden3-crypto/ff/element_test.go
ff/element_test.goRaw
1// Code generated by goff DO NOT EDIT
2package ff
3
4import (
5 "crypto/rand"
6 "math/big"
7 mrand "math/rand"
8 "testing"
9)
10
11func TestELEMENTCorrectnessAgainstBigInt(t *testing.T) {
12 modulus, _ := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
13 cmpEandB := func(e *Element, b *big.Int, name string) {
14 var _e big.Int
15 if e.FromMont().ToBigInt(&_e).Cmp(b) != 0 {
16 t.Fatal(name, "failed")
17 }
18 }
19 var modulusMinusOne, one big.Int
20 one.SetUint64(1)
21
22 modulusMinusOne.Sub(modulus, &one)
23
24 for i := 0; i < 1000; i++ {
25
26 // sample 2 random big int
27 b1, _ := rand.Int(rand.Reader, modulus)
28 b2, _ := rand.Int(rand.Reader, modulus)
29 rExp := mrand.Uint64()
30
31 // adding edge cases
32 // TODO need more edge cases
33 switch i {
34 case 0:
35 rExp = 0
36 b1.SetUint64(0)
37 case 1:
38 b2.SetUint64(0)
39 case 2:
40 b1.SetUint64(0)
41 b2.SetUint64(0)
42 case 3:
43 rExp = 0
44 case 4:
45 rExp = 1
46 case 5:
47 rExp = ^uint64(0) // max uint
48 case 6:
49 rExp = 2
50 b1.Set(&modulusMinusOne)
51 case 7:
52 b2.Set(&modulusMinusOne)
53 case 8:
54 b1.Set(&modulusMinusOne)
55 b2.Set(&modulusMinusOne)
56 }
57
58 rbExp := new(big.Int).SetUint64(rExp)
59
60 var bMul, bAdd, bSub, bDiv, bNeg, bLsh, bInv, bExp, bSquare big.Int
61
62 // e1 = mont(b1), e2 = mont(b2)
63 var e1, e2, eMul, eAdd, eSub, eDiv, eNeg, eLsh, eInv, eExp, eSquare, eMulAssign, eSubAssign, eAddAssign Element
64 e1.SetBigInt(b1)
65 e2.SetBigInt(b2)
66
67 // (e1*e2).FromMont() === b1*b2 mod q ... etc
68 eSquare.Square(&e1)
69 eMul.Mul(&e1, &e2)
70 eMulAssign.Set(&e1)
71 eMulAssign.MulAssign(&e2)
72 eAdd.Add(&e1, &e2)
73 eAddAssign.Set(&e1)
74 eAddAssign.AddAssign(&e2)
75 eSub.Sub(&e1, &e2)
76 eSubAssign.Set(&e1)
77 eSubAssign.SubAssign(&e2)
78 eDiv.Div(&e1, &e2)
79 eNeg.Neg(&e1)
80 eInv.Inverse(&e1)
81 eExp.Exp(e1, rExp)
82 eLsh.Double(&e1)
83
84 // same operations with big int
85 bAdd.Add(b1, b2).Mod(&bAdd, modulus)
86 bMul.Mul(b1, b2).Mod(&bMul, modulus)
87 bSquare.Mul(b1, b1).Mod(&bSquare, modulus)
88 bSub.Sub(b1, b2).Mod(&bSub, modulus)
89 bDiv.ModInverse(b2, modulus)
90 bDiv.Mul(&bDiv, b1).
91 Mod(&bDiv, modulus)
92 bNeg.Neg(b1).Mod(&bNeg, modulus)
93
94 bInv.ModInverse(b1, modulus)
95 bExp.Exp(b1, rbExp, modulus)
96 bLsh.Lsh(b1, 1).Mod(&bLsh, modulus)
97
98 cmpEandB(&eSquare, &bSquare, "Square")
99 cmpEandB(&eMul, &bMul, "Mul")
100 cmpEandB(&eMulAssign, &bMul, "MulAssign")
101 cmpEandB(&eAdd, &bAdd, "Add")
102 cmpEandB(&eAddAssign, &bAdd, "AddAssign")
103 cmpEandB(&eSub, &bSub, "Sub")
104 cmpEandB(&eSubAssign, &bSub, "SubAssign")
105 cmpEandB(&eDiv, &bDiv, "Div")
106 cmpEandB(&eNeg, &bNeg, "Neg")
107 cmpEandB(&eInv, &bInv, "Inv")
108 cmpEandB(&eExp, &bExp, "Exp")
109 cmpEandB(&eLsh, &bLsh, "Lsh")
110 }
111}
112
113func TestELEMENTIsRandom(t *testing.T) {
114 for i := 0; i < 1000; i++ {
115 var x, y Element
116 x.SetRandom()
117 y.SetRandom()
118 if x.Equal(&y) {
119 t.Fatal("2 random numbers are unlikely to be equal")
120 }
121 }
122}
123
124// -------------------------------------------------------------------------------------------------
125// benchmarks
126// most benchmarks are rudimentary and should sample a large number of random inputs
127// or be run multiple times to ensure it didn't measure the fastest path of the function
128// TODO: clean up and push benchmarking branch
129
130var benchResElement Element
131
132func BenchmarkInverseELEMENT(b *testing.B) {
133 var x Element
134 x.SetRandom()
135 benchResElement.SetRandom()
136 b.ResetTimer()
137
138 for i := 0; i < b.N; i++ {
139 benchResElement.Inverse(&x)
140 }
141
142}
143func BenchmarkExpELEMENT(b *testing.B) {
144 var x Element
145 x.SetRandom()
146 benchResElement.SetRandom()
147 b.ResetTimer()
148 for i := 0; i < b.N; i++ {
149 benchResElement.Exp(x, mrand.Uint64())
150 }
151}
152
153func BenchmarkDoubleELEMENT(b *testing.B) {
154 benchResElement.SetRandom()
155 b.ResetTimer()
156 for i := 0; i < b.N; i++ {
157 benchResElement.Double(&benchResElement)
158 }
159}
160
161func BenchmarkAddELEMENT(b *testing.B) {
162 var x Element
163 x.SetRandom()
164 benchResElement.SetRandom()
165 b.ResetTimer()
166 for i := 0; i < b.N; i++ {
167 benchResElement.Add(&x, &benchResElement)
168 }
169}
170
171func BenchmarkSubELEMENT(b *testing.B) {
172 var x Element
173 x.SetRandom()
174 benchResElement.SetRandom()
175 b.ResetTimer()
176 for i := 0; i < b.N; i++ {
177 benchResElement.Sub(&x, &benchResElement)
178 }
179}
180
181func BenchmarkNegELEMENT(b *testing.B) {
182 benchResElement.SetRandom()
183 b.ResetTimer()
184 for i := 0; i < b.N; i++ {
185 benchResElement.Neg(&benchResElement)
186 }
187}
188
189func BenchmarkDivELEMENT(b *testing.B) {
190 var x Element
191 x.SetRandom()
192 benchResElement.SetRandom()
193 b.ResetTimer()
194 for i := 0; i < b.N; i++ {
195 benchResElement.Div(&x, &benchResElement)
196 }
197}
198
199func BenchmarkFromMontELEMENT(b *testing.B) {
200 benchResElement.SetRandom()
201 b.ResetTimer()
202 for i := 0; i < b.N; i++ {
203 benchResElement.FromMont()
204 }
205}
206
207func BenchmarkToMontELEMENT(b *testing.B) {
208 benchResElement.SetRandom()
209 b.ResetTimer()
210 for i := 0; i < b.N; i++ {
211 benchResElement.ToMont()
212 }
213}
214func BenchmarkSquareELEMENT(b *testing.B) {
215 benchResElement.SetRandom()
216 b.ResetTimer()
217 for i := 0; i < b.N; i++ {
218 benchResElement.Square(&benchResElement)
219 }
220}
221
222func BenchmarkMulAssignELEMENT(b *testing.B) {
223 x := Element{
224 1997599621687373223,
225 6052339484930628067,
226 10108755138030829701,
227 150537098327114917,
228 }
229 benchResElement.SetOne()
230 b.ResetTimer()
231 for i := 0; i < b.N; i++ {
232 benchResElement.MulAssign(&x)
233 }
234}