github.com/emmansun/gmsm@v0.29.1/sm9/bn256/gfp_test.go (about) 1 package bn256 2 3 import ( 4 "encoding/hex" 5 "math/big" 6 "testing" 7 ) 8 9 func TestGfpBasicOperations(t *testing.T) { 10 x := fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")) 11 y := fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")) 12 expectedAdd := fromBigInt(bigFromHex("0691692307d370af56226e57920199fbbe10f216c67fbc9468c7f225a4b1f21f")) 13 expectedDouble := fromBigInt(bigFromHex("551de7a0ee24723edcf314ff72f478fac1c7c4e7044238acc3913cfbcdaf7d05")) 14 expectedSub := fromBigInt(bigFromHex("67b381821c52a5624f3304a8149be8461e3bc07adcb872c38aa65051ba53ba97")) 15 expectedNeg := fromBigInt(bigFromHex("7f1d8aad70909be90358f1d02240062433cc3a0248ded72febb879ec33ce6f22")) 16 expectedMul := fromBigInt(bigFromHex("3d08bbad376584e4f74bd31f78f716372b96ba8c3f939c12b8d54e79b6489e76")) 17 expectedMul2 := fromBigInt(bigFromHex("1df94a9e05a559ff38e0ab50cece734dc058d33738ceacaa15986a67cbff1ef6")) 18 19 t.Parallel() 20 t.Run("add", func(t *testing.T) { 21 ret := &gfP{} 22 gfpAdd(ret, x, y) 23 if *expectedAdd != *ret { 24 t.Errorf("add not same") 25 } 26 x1 := &gfP{} 27 x1.Set(x) 28 gfpAdd(x1, x1, y) 29 if *expectedAdd != *x1 { 30 t.Errorf("add not same when add self") 31 } 32 }) 33 34 t.Run("double", func(t *testing.T) { 35 ret := &gfP{} 36 gfpDouble(ret, x) 37 if ret.Equal(expectedDouble) != 1 { 38 t.Errorf("double not same, got %v, expected %v", ret, expectedDouble) 39 } 40 ret.Set(x) 41 gfpDouble(ret, ret) 42 if ret.Equal(expectedDouble) != 1 { 43 t.Errorf("double not same, got %v, expected %v", ret, expectedDouble) 44 } 45 }) 46 47 t.Run("triple", func(t *testing.T) { 48 expected := &gfP{} 49 gfpAdd(expected, x, expectedDouble) 50 ret := &gfP{} 51 ret.Set(x) 52 gfpTriple(ret, ret) 53 if ret.Equal(expected) != 1 { 54 t.Errorf("expected %v, got %v", expected, ret) 55 } 56 }) 57 58 t.Run("sub", func(t *testing.T) { 59 ret := &gfP{} 60 gfpSub(ret, y, x) 61 if *expectedSub != *ret { 62 t.Errorf("sub not same") 63 } 64 x1 := &gfP{} 65 x1.Set(x) 66 gfpSub(x1, y, x1) 67 if *expectedSub != *x1 { 68 t.Errorf("sub not same when sub self") 69 } 70 }) 71 72 t.Run("neg", func(t *testing.T) { 73 ret := &gfP{} 74 gfpNeg(ret, y) 75 if *expectedNeg != *ret { 76 t.Errorf("neg not same") 77 } 78 ret.Set(y) 79 gfpNeg(ret, ret) 80 if *expectedNeg != *ret { 81 t.Errorf("neg not same when neg self") 82 } 83 }) 84 85 t.Run("mul", func(t *testing.T) { 86 ret := &gfP{} 87 gfpMul(ret, x, y) 88 if *expectedMul != *ret { 89 t.Errorf("mul not same") 90 } 91 ret.Set(x) 92 gfpMul(ret, ret, y) 93 if *expectedMul != *ret { 94 t.Errorf("mul not same when mul self") 95 } 96 }) 97 98 t.Run("square", func(t *testing.T) { 99 ret, ret1, ret2 := &gfP{}, &gfP{}, &gfP{} 100 gfpMul(ret, x, y) 101 gfpMul(ret1, ret, ret) 102 if *ret1 != *expectedMul2 { 103 t.Errorf("mul not same") 104 } 105 gfpMul(ret1, ret1, ret1) 106 gfpSqr(ret2, ret, 2) 107 if *ret1 != *ret2 { 108 t.Errorf("mul/sqr not same") 109 } 110 ret2.Set(ret) 111 gfpSqr(ret2, ret2, 2) 112 if *ret1 != *ret2 { 113 t.Errorf("mul/sqr not same when square self") 114 } 115 }) 116 } 117 118 func TestGfpSqr(t *testing.T) { 119 t.Run("p-1", func(t *testing.T) { 120 pMinusOne := new(big.Int).Sub(p, big.NewInt(1)) 121 x := fromBigInt(pMinusOne) 122 ret := &gfP{} 123 gfpSqr(ret, x, 1) 124 pMinusOne.Mul(pMinusOne, pMinusOne) 125 pMinusOne.Mod(pMinusOne, p) 126 expected := fromBigInt(pMinusOne) 127 if *ret != *expected { 128 t.Errorf("bad sqr") 129 } 130 }) 131 t.Run("p+1", func(t *testing.T) { 132 pPlusOne := new(big.Int).Add(p, big.NewInt(1)) 133 x := fromBigInt(pPlusOne) 134 ret := &gfP{} 135 gfpSqr(ret, x, 1) 136 pPlusOne.Mul(pPlusOne, pPlusOne) 137 pPlusOne.Mod(pPlusOne, p) 138 if *ret != *fromBigInt(pPlusOne) { 139 t.Errorf("bad sqr") 140 } 141 }) 142 } 143 144 func TestFromMont(t *testing.T) { 145 x := fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")) 146 ret1, ret2 := &gfP{}, &gfP{} 147 gfpFromMont(ret1, x) 148 gfpMul(ret2, x, &gfP{1}) 149 if *ret1 != *ret2 { 150 t.Errorf("mul/fromMont not same") 151 } 152 } 153 154 func TestGfpExp(t *testing.T) { 155 xI := bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596") 156 x := fromBigInt(xI) 157 ret, ret3 := &gfP{}, &gfP{} 158 ret.exp(x, pMinus2) 159 160 gfpMul(ret3, x, ret) 161 if *ret3 != *one { 162 t.Errorf("got %v, expected %v\n", ret3, one) 163 } 164 montDecode(ret, ret) 165 166 ret2 := new(big.Int).Exp(xI, bigFromHex("b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457b"), p) 167 if hex.EncodeToString(ret2.Bytes()) != ret.String() { 168 t.Errorf("exp not same, got %v, expected %v\n", ret, hex.EncodeToString(ret2.Bytes())) 169 } 170 171 xInv := new(big.Int).ModInverse(xI, p) 172 if hex.EncodeToString(ret2.Bytes()) != hex.EncodeToString(xInv.Bytes()) { 173 t.Errorf("exp not same, got %v, expected %v\n", hex.EncodeToString(ret2.Bytes()), hex.EncodeToString(xInv.Bytes())) 174 } 175 176 x2 := new(big.Int).Mul(xI, xInv) 177 x2.Mod(x2, p) 178 if big.NewInt(1).Cmp(x2) != 0 { 179 t.Errorf("not same") 180 } 181 182 xInvGfp := fromBigInt(xInv) 183 gfpMul(ret, x, xInvGfp) 184 if *ret != *one { 185 t.Errorf("got %v, expected %v", ret, one) 186 } 187 } 188 189 func TestSqrt(t *testing.T) { 190 tests := []string{ 191 "9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596", 192 "92fe90b700fbd4d8cc177d300ed16e4e15471a681b2c9e3728c1b82c885e49c2", 193 } 194 for i, test := range tests { 195 y2 := bigFromHex(test) 196 y21 := new(big.Int).ModSqrt(y2, p) 197 198 y3 := new(big.Int).Mul(y21, y21) 199 y3.Mod(y3, p) 200 if y2.Cmp(y3) != 0 { 201 t.Error("Invalid sqrt") 202 } 203 204 tmp := fromBigInt(y2) 205 tmp.Sqrt(tmp) 206 montDecode(tmp, tmp) 207 var res [32]byte 208 tmp.Marshal(res[:]) 209 if hex.EncodeToString(res[:]) != hex.EncodeToString(y21.Bytes()) { 210 t.Errorf("case %v, got %v, expected %v\n", i, hex.EncodeToString(res[:]), hex.EncodeToString(y21.Bytes())) 211 } 212 } 213 } 214 215 func TestGeneratedSqrt(t *testing.T) { 216 tests := []string{ 217 "9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596", 218 "92fe90b700fbd4d8cc177d300ed16e4e15471a681b2c9e3728c1b82c885e49c2", 219 } 220 for i, test := range tests { 221 y2 := bigFromHex(test) 222 y21 := new(big.Int).ModSqrt(y2, p) 223 224 y3 := new(big.Int).Mul(y21, y21) 225 y3.Mod(y3, p) 226 if y2.Cmp(y3) != 0 { 227 t.Error("Invalid sqrt") 228 } 229 230 tmp := fromBigInt(y2) 231 e := &gfP{} 232 Sqrt(e, tmp) 233 montDecode(e, e) 234 var res [32]byte 235 e.Marshal(res[:]) 236 if hex.EncodeToString(res[:]) != hex.EncodeToString(y21.Bytes()) { 237 t.Errorf("case %v, got %v, expected %v\n", i, hex.EncodeToString(res[:]), hex.EncodeToString(y21.Bytes())) 238 } 239 } 240 } 241 242 func TestInvert(t *testing.T) { 243 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 244 xInv := &gfP{} 245 xInv.Invert(x) 246 y := &gfP{} 247 gfpMul(y, x, xInv) 248 if *y != *one { 249 t.Errorf("got %v, expected %v", y, one) 250 } 251 } 252 253 func TestGfpNeg(t *testing.T) { 254 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 255 got := &gfP{} 256 gfpSub(got, zero, x) 257 expected := &gfP{} 258 gfpNeg(expected, x) 259 if *expected != *got { 260 t.Errorf("got %v, expected %v", got, expected) 261 } 262 gfpSub(got, zero, zero) 263 gfpNeg(expected, zero) 264 if *expected != *got { 265 t.Errorf("got %v, expected %v", got, expected) 266 } 267 } 268 269 func BenchmarkGfPUnmarshal(b *testing.B) { 270 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 271 b.ReportAllocs() 272 b.ResetTimer() 273 var out [32]byte 274 x.Marshal(out[:]) 275 for i := 0; i < b.N; i++ { 276 x.Unmarshal(out[:]) 277 } 278 } 279 280 func BenchmarkGfPMul(b *testing.B) { 281 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 282 b.ReportAllocs() 283 b.ResetTimer() 284 ret := &gfP{} 285 for i := 0; i < b.N; i++ { 286 gfpMul(ret, x, x) 287 } 288 } 289 290 func BenchmarkGfPSqr(b *testing.B) { 291 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 292 b.ReportAllocs() 293 b.ResetTimer() 294 ret := &gfP{} 295 for i := 0; i < b.N; i++ { 296 gfpSqr(ret, x, 1) 297 } 298 } 299 300 func BenchmarkGfPTriple(b *testing.B) { 301 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 302 b.ReportAllocs() 303 b.ResetTimer() 304 ret := &gfP{} 305 for i := 0; i < b.N; i++ { 306 gfpTriple(ret, x) 307 } 308 } 309 310 func BenchmarkGfPTriple2(b *testing.B) { 311 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 312 b.ReportAllocs() 313 b.ResetTimer() 314 ret := &gfP{} 315 for i := 0; i < b.N; i++ { 316 gfpAdd(ret, x, x) 317 gfpAdd(ret, ret, x) 318 } 319 } 320 321 func BenchmarkGfPDouble(b *testing.B) { 322 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 323 b.ReportAllocs() 324 b.ResetTimer() 325 ret := &gfP{} 326 for i := 0; i < b.N; i++ { 327 gfpDouble(ret, x) 328 } 329 } 330 331 func BenchmarkGfPDouble2(b *testing.B) { 332 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 333 b.ReportAllocs() 334 b.ResetTimer() 335 ret := &gfP{} 336 for i := 0; i < b.N; i++ { 337 gfpAdd(ret, x, x) 338 } 339 } 340 341 func BenchmarkGfPNeg(b *testing.B) { 342 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 343 b.ReportAllocs() 344 b.ResetTimer() 345 ret := &gfP{} 346 for i := 0; i < b.N; i++ { 347 gfpNeg(ret, x) 348 } 349 } 350 351 func BenchmarkGfPNeg2(b *testing.B) { 352 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 353 b.ReportAllocs() 354 b.ResetTimer() 355 ret := &gfP{} 356 for i := 0; i < b.N; i++ { 357 gfpSub(ret, zero, x) 358 } 359 } 360 361 func BenchmarkGfPInvert(b *testing.B) { 362 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 363 b.ReportAllocs() 364 b.ResetTimer() 365 ret := &gfP{} 366 for i := 0; i < b.N; i++ { 367 ret.Invert(x) 368 } 369 } 370 371 func BenchmarkGfPInvert2(b *testing.B) { 372 x := fromBigInt(bigFromHex("9093a2b979e6186f43a9b28d41ba644d533377f2ede8c66b19774bf4a9c7a596")) 373 b.ReportAllocs() 374 b.ResetTimer() 375 ret := &gfP{} 376 for i := 0; i < b.N; i++ { 377 ret.exp(x, pMinus2) 378 } 379 }