github.com/cloudflare/circl@v1.5.0/ecc/bls12381/ff/scalar_test.go (about) 1 package ff_test 2 3 import ( 4 "bytes" 5 "crypto/rand" 6 "math/big" 7 "testing" 8 9 "github.com/cloudflare/circl/ecc/bls12381/ff" 10 "github.com/cloudflare/circl/internal/test" 11 ) 12 13 func randomScalar(t testing.TB) *ff.Scalar { 14 t.Helper() 15 s := new(ff.Scalar) 16 err := s.Random(rand.Reader) 17 if err != nil { 18 t.Error(err) 19 } 20 return s 21 } 22 23 func TestScalar(t *testing.T) { 24 const testTimes = 1 << 10 25 t.Run("marshal", func(t *testing.T) { 26 for i := 0; i < testTimes; i++ { 27 var y ff.Scalar 28 x := randomScalar(t) 29 30 bytes, err := x.MarshalBinary() 31 if err != nil { 32 test.ReportError(t, x, y, x) 33 } 34 err = y.UnmarshalBinary(bytes) 35 if err != nil { 36 test.ReportError(t, x, y, x) 37 } 38 if x.IsEqual(&y) == 0 { 39 test.ReportError(t, x, y, x) 40 } 41 } 42 }) 43 t.Run("no_alias", func(t *testing.T) { 44 var want, got ff.Scalar 45 x := randomScalar(t) 46 got.Set(x) 47 got.Sqr(&got) 48 want.Set(x) 49 want.Mul(&want, &want) 50 if got.IsEqual(&want) == 0 { 51 test.ReportError(t, got, want, x) 52 } 53 }) 54 t.Run("mul_inv", func(t *testing.T) { 55 var z ff.Scalar 56 for i := 0; i < testTimes; i++ { 57 x := randomScalar(t) 58 y := randomScalar(t) 59 // x*y*x^1 - y = 0 60 z.Inv(x) 61 z.Mul(&z, y) 62 z.Mul(&z, x) 63 z.Sub(&z, y) 64 got := z.IsZero() 65 want := 1 66 if got != want { 67 test.ReportError(t, got, want, x, y) 68 } 69 } 70 }) 71 t.Run("mul_sqr", func(t *testing.T) { 72 var l0, l1, r0, r1 ff.Scalar 73 for i := 0; i < testTimes; i++ { 74 x := randomScalar(t) 75 y := randomScalar(t) 76 77 // (x+y)(x-y) = (x^2-y^2) 78 l0.Add(x, y) 79 l1.Sub(x, y) 80 l0.Mul(&l0, &l1) 81 r0.Sqr(x) 82 r1.Sqr(y) 83 r0.Sub(&r0, &r1) 84 got := &l0 85 want := &r0 86 if got.IsEqual(want) == 0 { 87 test.ReportError(t, got, want, x, y) 88 } 89 } 90 }) 91 t.Run("bytes", func(t *testing.T) { 92 var data [100]byte 93 _, _ = rand.Read(data[:]) 94 95 var a, b ff.Scalar 96 var bigA, bigOrder big.Int 97 bigOrder.SetBytes(ff.ScalarOrder()) 98 99 for i := 0; i < 100; i++ { 100 a.SetBytes(data[:i]) 101 102 bigA.SetBytes(data[:i]) 103 bigA.Mod(&bigA, &bigOrder) 104 bytesA := bigA.Bytes() 105 b.SetBytes(bytesA) 106 107 if a.IsEqual(&b) == 0 { 108 test.ReportError(t, a, b) 109 } 110 111 got, err := a.MarshalBinary() 112 test.CheckNoErr(t, err, "MarshalBinary failed") 113 want, err := b.MarshalBinary() 114 test.CheckNoErr(t, err, "MarshalBinary failed") 115 116 if !bytes.Equal(got, want) { 117 test.ReportError(t, got, want) 118 } 119 } 120 }) 121 } 122 123 func BenchmarkScalar(b *testing.B) { 124 x := randomScalar(b) 125 y := randomScalar(b) 126 z := randomScalar(b) 127 128 b.Run("Add", func(b *testing.B) { 129 for i := 0; i < b.N; i++ { 130 z.Add(x, y) 131 } 132 }) 133 b.Run("Mul", func(b *testing.B) { 134 for i := 0; i < b.N; i++ { 135 z.Mul(x, y) 136 } 137 }) 138 b.Run("Sqr", func(b *testing.B) { 139 for i := 0; i < b.N; i++ { 140 z.Sqr(x) 141 } 142 }) 143 b.Run("Inv", func(b *testing.B) { 144 for i := 0; i < b.N; i++ { 145 z.Inv(x) 146 } 147 }) 148 }