github.com/cloudflare/circl@v1.5.0/ecc/p384/arith_test.go (about)

     1  //go:build (!purego && arm64) || (!purego && amd64)
     2  // +build !purego,arm64 !purego,amd64
     3  
     4  package p384
     5  
     6  import (
     7  	"crypto/elliptic"
     8  	"crypto/rand"
     9  	"math/big"
    10  	"testing"
    11  
    12  	"github.com/cloudflare/circl/internal/test"
    13  )
    14  
    15  func TestFpCmov(t *testing.T) {
    16  	var x, y, z fp384
    17  	for _, b := range []int{-2, -1, 1, 2} {
    18  		_, _ = rand.Read(x[:])
    19  		_, _ = rand.Read(y[:])
    20  		z = x
    21  		fp384Cmov(&z, &y, b)
    22  		got := z
    23  		want := y
    24  		if got != want {
    25  			test.ReportError(t, got, want, b, x, y)
    26  		}
    27  	}
    28  	_, _ = rand.Read(x[:])
    29  	_, _ = rand.Read(y[:])
    30  	z = x
    31  	fp384Cmov(&z, &y, 0)
    32  	got := z
    33  	want := x
    34  	if got != want {
    35  		test.ReportError(t, got, want, 0, x, y)
    36  	}
    37  }
    38  
    39  func TestFpNegZero(t *testing.T) {
    40  	zero, x := &fp384{}, &fp384{}
    41  	fp384Neg(x, zero)
    42  	got := x.BigInt()
    43  	want := zero.BigInt()
    44  	if got.Cmp(want) != 0 {
    45  		test.ReportError(t, got, want, x)
    46  	}
    47  }
    48  
    49  func TestFpSetBigInt(t *testing.T) {
    50  	P := elliptic.P384().Params().P
    51  
    52  	neg := big.NewInt(-0xFF)                       // negative
    53  	zero := big.NewInt(0)                          // zero
    54  	one := big.NewInt(1)                           // one
    55  	two96 := new(big.Int).Lsh(one, 96)             // 2^96
    56  	two384 := new(big.Int).Lsh(one, 384)           // 2^384
    57  	two384two96 := new(big.Int).Sub(two384, two96) // 2^384-2^96
    58  	two768 := new(big.Int).Lsh(one, 768)           // 2^768
    59  
    60  	for id, b := range []*big.Int{
    61  		neg, zero, one, two96, two384, two384two96, two768,
    62  	} {
    63  		var x fp384
    64  		x.SetBigInt(b)
    65  		got := x.BigInt()
    66  		if b.BitLen() > 384 || b.Sign() < 0 {
    67  			b.Mod(b, P)
    68  		}
    69  		want := b
    70  		if got.Cmp(want) != 0 {
    71  			test.ReportError(t, got, want, id)
    72  		}
    73  	}
    74  }
    75  
    76  func TestMulZero(t *testing.T) {
    77  	x, zero := &fp384{}, &fp384{}
    78  	_, _ = rand.Read(x[:])
    79  
    80  	fp384Mul(x, x, zero)
    81  	got := x.BigInt()
    82  	want := zero.BigInt()
    83  
    84  	if got.Cmp(want) != 0 {
    85  		test.ReportError(t, got, want, x)
    86  	}
    87  }
    88  
    89  func TestFp(t *testing.T) {
    90  	P := elliptic.P384().Params().P
    91  	x, y, z := &fp384{}, &fp384{}, &fp384{}
    92  	testTimes := 1 << 12
    93  	var bigR, bigR2, bigRinv big.Int
    94  	one := big.NewInt(1)
    95  	bigR.Lsh(one, 384).Mod(&bigR, P)
    96  	bigR2.Lsh(one, 2*384).Mod(&bigR2, P)
    97  	bigRinv.ModInverse(&bigR, P)
    98  
    99  	t.Run("Encode", func(t *testing.T) {
   100  		for i := 0; i < testTimes; i++ {
   101  			_, _ = rand.Read(x[:])
   102  			bigX := x.BigInt()
   103  			// fp384
   104  			montEncode(z, x)
   105  			got := z.BigInt()
   106  			// big.Int
   107  			want := bigX.Mul(bigX, &bigR).Mod(bigX, P)
   108  			if got.Cmp(want) != 0 {
   109  				test.ReportError(t, got, want, x)
   110  			}
   111  		}
   112  	})
   113  	t.Run("Decode", func(t *testing.T) {
   114  		for i := 0; i < testTimes; i++ {
   115  			_, _ = rand.Read(x[:])
   116  			bigX := x.BigInt()
   117  			// fp384
   118  			montDecode(z, x)
   119  			got := z.BigInt()
   120  			// big.Int
   121  			want := bigX.Mul(bigX, new(big.Int).ModInverse(&bigR, P)).Mod(bigX, P)
   122  			if got.Cmp(want) != 0 {
   123  				test.ReportError(t, got, want, x)
   124  			}
   125  		}
   126  	})
   127  	t.Run("Neg", func(t *testing.T) {
   128  		for i := 0; i < testTimes; i++ {
   129  			_, _ = rand.Read(x[:])
   130  			bigX := x.BigInt()
   131  			// fp384
   132  			fp384Neg(z, x)
   133  			got := z.BigInt()
   134  			// big.Int
   135  			want := bigX.Neg(bigX).Mod(bigX, P)
   136  			if got.Cmp(want) != 0 {
   137  				test.ReportError(t, got, want, x)
   138  			}
   139  		}
   140  	})
   141  	t.Run("Add", func(t *testing.T) {
   142  		for i := 0; i < testTimes; i++ {
   143  			_, _ = rand.Read(x[:])
   144  			_, _ = rand.Read(y[:])
   145  			bigX := x.BigInt()
   146  			bigY := y.BigInt()
   147  			// fp384
   148  			fp384Add(z, x, y)
   149  			got := z.BigInt()
   150  			// big.Int
   151  			want := bigX.Add(bigX, bigY)
   152  			want = want.Mod(want, P)
   153  			if got.Cmp(want) != 0 {
   154  				test.ReportError(t, got, want, x, y)
   155  			}
   156  		}
   157  	})
   158  	t.Run("Sub", func(t *testing.T) {
   159  		for i := 0; i < testTimes; i++ {
   160  			_, _ = rand.Read(x[:])
   161  			_, _ = rand.Read(y[:])
   162  			bigX := x.BigInt()
   163  			bigY := y.BigInt()
   164  			// fp384
   165  			fp384Sub(z, x, y)
   166  			got := z.BigInt()
   167  			// big.Int
   168  			want := bigX.Sub(bigX, bigY)
   169  			want = want.Mod(want, P)
   170  			if got.Cmp(want) != 0 {
   171  				test.ReportError(t, got, want, x, y)
   172  			}
   173  		}
   174  	})
   175  	t.Run("Mul", func(t *testing.T) {
   176  		for i := 0; i < testTimes; i++ {
   177  			_, _ = rand.Read(x[:])
   178  			_, _ = rand.Read(y[:])
   179  			bigX := x.BigInt()
   180  			bigY := y.BigInt()
   181  			// fp384
   182  			fp384Mul(z, x, y)
   183  			got := z.BigInt()
   184  			// big.Int
   185  			want := bigX.Mul(bigX, bigY).Mul(bigX, &bigRinv).Mod(bigX, P)
   186  			if got.Cmp(want) != 0 {
   187  				test.ReportError(t, got, want, x, y)
   188  			}
   189  		}
   190  	})
   191  	t.Run("Inv", func(t *testing.T) {
   192  		for i := 0; i < testTimes; i++ {
   193  			_, _ = rand.Read(x[:])
   194  			bigX := x.BigInt()
   195  			// fp384
   196  			fp384Inv(z, x)
   197  			got := z.BigInt()
   198  			// big.Int
   199  			want := bigX.ModInverse(bigX, P).Mul(bigX, &bigR2).Mod(bigX, P)
   200  			if got.Cmp(want) != 0 {
   201  				test.ReportError(t, got, want, x)
   202  			}
   203  		}
   204  	})
   205  }
   206  
   207  func BenchmarkFp(b *testing.B) {
   208  	x, y, z := &fp384{}, &fp384{}, &fp384{}
   209  
   210  	b.Run("Add", func(b *testing.B) {
   211  		for i := 0; i < b.N; i++ {
   212  			fp384Add(z, x, y)
   213  		}
   214  	})
   215  
   216  	b.Run("Sub", func(b *testing.B) {
   217  		for i := 0; i < b.N; i++ {
   218  			fp384Sub(z, x, y)
   219  		}
   220  	})
   221  
   222  	b.Run("Mul", func(b *testing.B) {
   223  		for i := 0; i < b.N; i++ {
   224  			fp384Mul(z, x, y)
   225  		}
   226  	})
   227  
   228  	b.Run("Sqr", func(b *testing.B) {
   229  		for i := 0; i < b.N; i++ {
   230  			fp384Sqr(z, x)
   231  		}
   232  	})
   233  
   234  	b.Run("Inv", func(b *testing.B) {
   235  		for i := 0; i < b.N; i++ {
   236  			fp384Inv(z, x)
   237  		}
   238  	})
   239  }