// Code generated by go generate; DO NOT EDIT. // This file was generated by robots. package p503 import ( "math/rand" "reflect" "testing" "testing/quick" "github.com/henrydcase/nobs/dh/sidh/internal/common" ) type testParams struct { Point common.ProjectivePoint Cparam common.ProjectiveCurveParameters ExtElem common.Fp2 } // Returns true if lhs = rhs. Takes variable time. func vartimeEqFp2(lhs, rhs *common.Fp2) bool { a := *lhs b := *rhs modP503(&a.A) modP503(&a.B) modP503(&b.A) modP503(&b.B) eq := true for i := 0; i < FpWords && eq; i++ { eq = eq && (a.A[i] == b.A[i]) eq = eq && (a.B[i] == b.B[i]) } return eq } func (testParams) generateFp2(rand *rand.Rand) common.Fp2 { // Generation strategy: low limbs taken from [0,2^64); high limb // taken from smaller range // // Size hint is ignored since all elements are fixed size. // // Field elements taken in range [0,2p). Emulate this by capping // the high limb by the top digit of 2*p-1: // // sage: (2*p-1).digits(2^64)[-1] // // This still allows generating values >= 2p, but hopefully that // excess is OK (and if it's not, we'll find out, because it's for // testing...) highLimb := rand.Uint64() % P503x2[FpWords-1] fpElementGen := func() (fp common.Fp) { for i := 0; i < (FpWords - 1); i++ { fp[i] = rand.Uint64() } fp[FpWords-1] = highLimb return fp } return common.Fp2{A: fpElementGen(), B: fpElementGen()} } func (c testParams) Generate(rand *rand.Rand, size int) reflect.Value { return reflect.ValueOf( testParams{ common.ProjectivePoint{ X: c.generateFp2(rand), Z: c.generateFp2(rand), }, common.ProjectiveCurveParameters{ A: c.generateFp2(rand), C: c.generateFp2(rand), }, c.generateFp2(rand), }) } func TestOne(t *testing.T) { var tmp common.Fp2 mul(&tmp, ¶ms.OneFp2, ¶ms.A.AffineP) if !vartimeEqFp2(&tmp, ¶ms.A.AffineP) { t.Error("Not equal 1") } } func TestFp2ToBytesRoundTrip(t *testing.T) { roundTrips := func(x testParams) bool { var xBytes = make([]byte, 2*params.Bytelen) var xPrime common.Fp2 common.Fp2ToBytes(xBytes[:], &x.ExtElem, params.Bytelen) common.BytesToFp2(&xPrime, xBytes[:], params.Bytelen) return vartimeEqFp2(&xPrime, &x.ExtElem) } if err := quick.Check(roundTrips, quickCheckConfig); err != nil { t.Error(err) } } func TestFp2MulDistributesOverAdd(t *testing.T) { mulDistributesOverAdd := func(x, y, z testParams) bool { // Compute t1 = (x+y)*z t1 := new(common.Fp2) add(t1, &x.ExtElem, &y.ExtElem) mul(t1, t1, &z.ExtElem) // Compute t2 = x*z + y*z t2 := new(common.Fp2) t3 := new(common.Fp2) mul(t2, &x.ExtElem, &z.ExtElem) mul(t3, &y.ExtElem, &z.ExtElem) add(t2, t2, t3) return vartimeEqFp2(t1, t2) } if err := quick.Check(mulDistributesOverAdd, quickCheckConfig); err != nil { t.Error(err) } } func TestFp2MulIsAssociative(t *testing.T) { isAssociative := func(x, y, z testParams) bool { // Compute t1 = (x*y)*z t1 := new(common.Fp2) mul(t1, &x.ExtElem, &y.ExtElem) mul(t1, t1, &z.ExtElem) // Compute t2 = (y*z)*x t2 := new(common.Fp2) mul(t2, &y.ExtElem, &z.ExtElem) mul(t2, t2, &x.ExtElem) return vartimeEqFp2(t1, t2) } if err := quick.Check(isAssociative, quickCheckConfig); err != nil { t.Error(err) } } func TestFp2SquareMatchesMul(t *testing.T) { sqrMatchesMul := func(x testParams) bool { // Compute t1 = (x*x) t1 := new(common.Fp2) mul(t1, &x.ExtElem, &x.ExtElem) // Compute t2 = x^2 t2 := new(common.Fp2) sqr(t2, &x.ExtElem) return vartimeEqFp2(t1, t2) } if err := quick.Check(sqrMatchesMul, quickCheckConfig); err != nil { t.Error(err) } } func TestFp2Inv(t *testing.T) { inverseIsCorrect := func(x testParams) bool { z := new(common.Fp2) inv(z, &x.ExtElem) // Now z = (1/x), so (z * x) * x == x mul(z, z, &x.ExtElem) mul(z, z, &x.ExtElem) return vartimeEqFp2(z, &x.ExtElem) } // This is more expensive; run fewer tests var quickCheckConfig = &quick.Config{MaxCount: (1 << 11)} if err := quick.Check(inverseIsCorrect, quickCheckConfig); err != nil { t.Error(err) } } func TestFp2Batch3Inv(t *testing.T) { batchInverseIsCorrect := func(x1, x2, x3 testParams) bool { var x1Inv, x2Inv, x3Inv common.Fp2 inv(&x1Inv, &x1.ExtElem) inv(&x2Inv, &x2.ExtElem) inv(&x3Inv, &x3.ExtElem) var y1, y2, y3 common.Fp2 Fp2Batch3Inv(&x1.ExtElem, &x2.ExtElem, &x3.ExtElem, &y1, &y2, &y3) return (vartimeEqFp2(&x1Inv, &y1) && vartimeEqFp2(&x2Inv, &y2) && vartimeEqFp2(&x3Inv, &y3)) } // This is more expensive; run fewer tests var quickCheckConfig = &quick.Config{MaxCount: (1 << 8)} if err := quick.Check(batchInverseIsCorrect, quickCheckConfig); err != nil { t.Error(err) } } func BenchmarkFp2Mul(b *testing.B) { z := &common.Fp2{A: bench_x, B: bench_y} w := new(common.Fp2) for n := 0; n < b.N; n++ { mul(w, z, z) } } func BenchmarkFp2Inv(b *testing.B) { z := &common.Fp2{A: bench_x, B: bench_y} w := new(common.Fp2) for n := 0; n < b.N; n++ { inv(w, z) } } func BenchmarkFp2Square(b *testing.B) { z := &common.Fp2{A: bench_x, B: bench_y} w := new(common.Fp2) for n := 0; n < b.N; n++ { sqr(w, z) } } func BenchmarkFp2Add(b *testing.B) { z := &common.Fp2{A: bench_x, B: bench_y} w := new(common.Fp2) for n := 0; n < b.N; n++ { add(w, z, z) } } func BenchmarkFp2Sub(b *testing.B) { z := &common.Fp2{A: bench_x, B: bench_y} w := new(common.Fp2) for n := 0; n < b.N; n++ { sub(w, z, z) } }