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 }