arnaucube
arnaucube/go-iden3-cryptoPublic Self-hosted repository
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}