github.com/cloudflare/circl@v1.5.0/ecc/goldilocks/scalar_test.go (about)

     1  package goldilocks_test
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/binary"
     6  	"math/big"
     7  	"testing"
     8  
     9  	"github.com/cloudflare/circl/ecc/goldilocks"
    10  	"github.com/cloudflare/circl/internal/conv"
    11  	"github.com/cloudflare/circl/internal/test"
    12  )
    13  
    14  func TestReduceModOrder(t *testing.T) {
    15  	order := goldilocks.Curve{}.Order()
    16  	bigOrder := conv.BytesLe2BigInt(order[:])
    17  	const max = 3*goldilocks.ScalarSize - 1
    18  	var b [max]byte
    19  	_, _ = rand.Read(b[:])
    20  	var z goldilocks.Scalar
    21  	for i := 0; i < max; i++ {
    22  		x := b[0:i]
    23  		bigX := conv.BytesLe2BigInt(x)
    24  
    25  		z.FromBytes(x)
    26  		got := conv.BytesLe2BigInt(z[:])
    27  		got.Mod(got, bigOrder)
    28  
    29  		want := bigX.Mod(bigX, bigOrder)
    30  
    31  		if got.Cmp(want) != 0 {
    32  			test.ReportError(t, got, want, x, i)
    33  		}
    34  	}
    35  }
    36  
    37  func testOp(t *testing.T,
    38  	f func(z, x, y *goldilocks.Scalar),
    39  	g func(z, x, y *big.Int),
    40  ) {
    41  	const testTimes = 1 << 8
    42  	var x, y, z goldilocks.Scalar
    43  	order := goldilocks.Curve{}.Order()
    44  	want := new(big.Int)
    45  	bigOrder := conv.BytesLe2BigInt(order[:])
    46  
    47  	for i := 0; i < testTimes; i++ {
    48  		_, _ = rand.Read(x[:])
    49  		_, _ = rand.Read(y[:])
    50  		bigX := conv.BytesLe2BigInt(x[:])
    51  		bigY := conv.BytesLe2BigInt(y[:])
    52  
    53  		f(&z, &x, &y)
    54  		got := conv.BytesLe2BigInt(z[:])
    55  
    56  		g(want, bigX, bigY)
    57  		want.Mod(want, bigOrder)
    58  		if got.Cmp(want) != 0 {
    59  			test.ReportError(t, got.Text(16), want.Text(16),
    60  				conv.BytesLe2Hex(x[:]),
    61  				conv.BytesLe2Hex(y[:]))
    62  		}
    63  	}
    64  }
    65  
    66  func TestScalar(t *testing.T) {
    67  	t.Run("Add", func(t *testing.T) {
    68  		testOp(t,
    69  			func(z, x, y *goldilocks.Scalar) { z.Add(x, y) },
    70  			func(z, x, y *big.Int) { z.Add(x, y) })
    71  	})
    72  	t.Run("Sub", func(t *testing.T) {
    73  		testOp(t,
    74  			func(z, x, y *goldilocks.Scalar) { z.Sub(x, y) },
    75  			func(z, x, y *big.Int) { z.Sub(x, y) })
    76  	})
    77  	t.Run("Mul", func(t *testing.T) {
    78  		testOp(t,
    79  			func(z, x, y *goldilocks.Scalar) { z.Mul(x, y) },
    80  			func(z, x, y *big.Int) { z.Mul(x, y) })
    81  	})
    82  }
    83  
    84  func BenchmarkScalar(b *testing.B) {
    85  	var k [2 * goldilocks.ScalarSize]byte
    86  	var x, y, z goldilocks.Scalar
    87  	_ = binary.Read(rand.Reader, binary.LittleEndian, x[:])
    88  	b.Run("Add", func(b *testing.B) {
    89  		for i := 0; i < b.N; i++ {
    90  			z.Add(&x, &y)
    91  		}
    92  	})
    93  	b.Run("Sub", func(b *testing.B) {
    94  		for i := 0; i < b.N; i++ {
    95  			z.Sub(&x, &y)
    96  		}
    97  	})
    98  	b.Run("Mul", func(b *testing.B) {
    99  		for i := 0; i < b.N; i++ {
   100  			z.Mul(&x, &y)
   101  		}
   102  	})
   103  	b.Run("Red", func(b *testing.B) {
   104  		for i := 0; i < b.N; i++ {
   105  			z.FromBytes(k[:])
   106  		}
   107  	})
   108  }