github.com/emmansun/gmsm@v0.29.1/sm9/bn256/gfp12_test.go (about) 1 package bn256 2 3 import ( 4 "math/big" 5 "testing" 6 ) 7 8 var testdataP4 = gfP4{ 9 gfP2{ 10 *fromBigInt(bigFromHex("85AEF3D078640C98597B6027B441A01FF1DD2C190F5E93C454806C11D8806141")), 11 *fromBigInt(bigFromHex("3722755292130B08D2AAB97FD34EC120EE265948D19C17ABF9B7213BAF82D65B")), 12 }, 13 gfP2{ 14 *fromBigInt(bigFromHex("17509B092E845C1266BA0D262CBEE6ED0736A96FA347C8BD856DC76B84EBEB96")), 15 *fromBigInt(bigFromHex("A7CF28D519BE3DA65F3170153D278FF247EFBA98A71A08116215BBA5C999A7C7")), 16 }, 17 } 18 19 func TestGfp12BasicOperations(t *testing.T) { 20 x := &gfP12{ 21 testdataP4, 22 testdataP4, 23 *(&gfP4{}).SetOne(), 24 } 25 y := &gfP12{ 26 testdataP4, 27 testdataP4, 28 *(&gfP4{}).SetZero(), 29 } 30 31 t.Parallel() 32 t.Run("Add", func(t *testing.T) { 33 expectedAdd := "(((6a6225e56e1acd7c5ae45b0f1b63733de799936987c8f38dd16bcddc6b500bcf, 0db9e03175ebe2b21be74db56d03e143dbd835729d7291fa6694b22536746fa1), (4d8891878c3113b4665011d7b24f278d4c1b54a22ec093840a00c030b5c239f9, 21092bc181ec5d9c488aac3c5feef9b725f7568b42b4794f807e271f22e38494)), ((6a6225e56e1acd7c5ae45b0f1b63733de799936987c8f38dd16bcddc6b500bcf, 0db9e03175ebe2b21be74db56d03e143dbd835729d7291fa6694b22536746fa1), (4d8891878c3113b4665011d7b24f278d4c1b54a22ec093840a00c030b5c239f9, 21092bc181ec5d9c488aac3c5feef9b725f7568b42b4794f807e271f22e38494)), ((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 49bffffffd5c590e29fc54b00a7138bade0d6cb4e58511241a9064d81caeba83)))" 34 got := &gfP12{} 35 got.Set(x) 36 got.Add(got, y) 37 38 if got.String() != expectedAdd { 39 t.Errorf("got %v, expected %v", got, expectedAdd) 40 } 41 }) 42 43 t.Run("Sub", func(t *testing.T) { 44 expectedSub := "(((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000)), ((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000)), ((0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000), (0000000000000000000000000000000000000000000000000000000000000000, 49bffffffd5c590e29fc54b00a7138bade0d6cb4e58511241a9064d81caeba83)))" 45 got := &gfP12{} 46 got.Set(x) 47 got.Sub(got, y) 48 49 if got.String() != expectedSub { 50 t.Errorf("got %v, expected %v", got, expectedSub) 51 } 52 }) 53 54 t.Run("Mul", func(t *testing.T) { 55 expectedMul := "(((2302538ca37ab5cf8c253b56ece9734f92e31f026e5bea5f178828769a8e2322, 96fe2ddc0dda2779d93b9d8560eebd91bb61e659c81a9936dac9a2bcc3f8ab86), (2c371ba768b6f660eaba367b2c444295e529efc2a5ad95d8f80265235ad4c6c9, 4f24d79c798eb4d8c2005bf43cb955f5420baf40650c750f4f0f1c0a11882a1c)), ((3aa3e5d659abd344e5045b16e0ce686e32e90f265231c5dddbb7ebf9359bafb4, a09d31d474e04adc96b08258be0b2d5e2df568599fa8f8d2b4d22f210cf94261), (00a5868716591909286c54468e0599715190e2a67646ab1fc7100e9aa04e4b35, 34e214ace81b90ab66df3a7f7188097a54cf00aa4c6b5b77629a907ec7a587d5)), ((0ae5a5c7453cd90d6f245b1ea6395d9e7e388ae31c9a982de6040a15ffe75399, 7d40837771310c153b760bac1983b2335e2007f5876470cf1da010f5002ccfa4), (6a027b86a324c54fc08c42055f4ad29a78f903f5d847b197698ef82c6e2ba1ee, 48bafd984e4ac3ba8533c8c28321193d83a6aac956223d9f44b6f9de6c678b16)))" 56 got := &gfP12{} 57 got.Set(x) 58 got.Mul(got, y) 59 60 if got.String() != expectedMul { 61 t.Errorf("got %v, expected %v", got, expectedMul) 62 } 63 }) 64 65 t.Run("Square", func(t *testing.T) { 66 got := &gfP12{} 67 got.Set(x) 68 got.Square(got) 69 70 expected := (&gfP12{}).Mul(x, x) 71 72 if *expected != *got { 73 t.Errorf("got %v, expected %v", got, expected) 74 } 75 }) 76 } 77 78 func TestGfp12Order(t *testing.T) { 79 in := &gfP12{ 80 testdataP4, 81 testdataP4, 82 *(&gfP4{}).SetOne(), 83 } 84 85 p6 := (&gfP12{}).FrobeniusP6(in) 86 p12 := (&gfP12{}).FrobeniusP6(p6) 87 if *p12 != *in { 88 t.Errorf("in^(p^12) not equal with in") 89 } 90 91 p2 := (&gfP12{}).FrobeniusP2(in) 92 p4 := (&gfP12{}).FrobeniusP2(p2) 93 p6_1 := (&gfP12{}).FrobeniusP2(p4) 94 p8 := (&gfP12{}).FrobeniusP2(p6_1) 95 p10 := (&gfP12{}).FrobeniusP2(p8) 96 p12_1 := (&gfP12{}).FrobeniusP2(p10) 97 if *p12_1 != *in { 98 t.Errorf("in^(p^12) not equal with in") 99 } 100 101 p3 := (&gfP12{}).FrobeniusP3(in) 102 p6_2 := (&gfP12{}).FrobeniusP3(p3) 103 p9 := (&gfP12{}).FrobeniusP3(p6_2) 104 p12_2 := (&gfP12{}).FrobeniusP3(p9) 105 if *p12_2 != *in { 106 t.Errorf("in^(p^12) not equal with in") 107 } 108 } 109 110 func TestCyclo6Square(t *testing.T) { 111 in := &gfP12{ 112 testdataP4, 113 testdataP4, 114 *(&gfP4{}).SetOne(), 115 } 116 117 // This is the p^6-Frobenius 118 t1 := (&gfP12{}).FrobeniusP6(in) 119 120 inv := (&gfP12{}).Invert(in) 121 t1.Mul(t1, inv) 122 123 t2 := inv.FrobeniusP2(t1) // reuse inv 124 t1.Mul(t1, t2) // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation 125 126 one := (&gfP12{}).SetOne() 127 t3 := (&gfP12{}).FrobeniusP2(t1) 128 t4 := (&gfP12{}).FrobeniusP2(t3) 129 t5 := (&gfP12{}).Invert(t3) 130 t5.Mul(t4, t5).Mul(t1, t5) 131 if *t5 != *one { 132 t.Errorf("t1 should be in Cyclotomic Subgroup") 133 } 134 135 got := &gfP12{} 136 expected := &gfP12{} 137 got.Cyclo6Square(t1) 138 expected.Square(t1) 139 if *got != *expected { 140 t.Errorf("not same got=%v, expected=%v", got, expected) 141 } 142 } 143 144 func BenchmarkGfP12Square(b *testing.B) { 145 x := &gfP12{ 146 testdataP4, 147 testdataP4, 148 *(&gfP4{}).SetOne(), 149 } 150 x2 := &gfP12{} 151 b.ReportAllocs() 152 b.ResetTimer() 153 for i := 0; i < b.N; i++ { 154 x2.Square(x) 155 } 156 } 157 158 func BenchmarkGfP12Cyclo6Square(b *testing.B) { 159 in := &gfP12{ 160 testdataP4, 161 testdataP4, 162 *(&gfP4{}).SetOne(), 163 } 164 165 // This is the p^6-Frobenius 166 t1 := (&gfP12{}).FrobeniusP6(in) 167 168 inv := (&gfP12{}).Invert(in) 169 t1.Mul(t1, inv) 170 171 t2 := inv.FrobeniusP2(t1) // reuse inv 172 t1.Mul(t1, t2) // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation 173 x2 := &gfP12{} 174 b.ReportAllocs() 175 b.ResetTimer() 176 for i := 0; i < b.N; i++ { 177 x2.Cyclo6Square(t1) 178 } 179 } 180 181 func BenchmarkGfP12SpecialSqures(b *testing.B) { 182 in := &gfP12{ 183 testdataP4, 184 testdataP4, 185 *(&gfP4{}).SetOne(), 186 } 187 188 // This is the p^6-Frobenius 189 t1 := (&gfP12{}).FrobeniusP6(in) 190 191 inv := (&gfP12{}).Invert(in) 192 t1.Mul(t1, inv) 193 194 t2 := inv.FrobeniusP2(t1) // reuse inv 195 t1.Mul(t1, t2) // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation 196 got := &gfP12{} 197 b.ReportAllocs() 198 b.ResetTimer() 199 for i := 0; i < b.N; i++ { 200 got.Cyclo6Squares(in, 61) 201 } 202 } 203 204 func testGfP12Invert(t *testing.T, x *gfP12) { 205 xInv := &gfP12{} 206 xInv.Invert(x) 207 208 y := &gfP12{} 209 y.Mul(x, xInv) 210 if !y.IsOne() { 211 t.Fail() 212 } 213 } 214 215 func Test_gfP12Invert(t *testing.T) { 216 x := &gfP12{ 217 testdataP4, 218 testdataP4, 219 *(&gfP4{}).SetOne(), 220 } 221 testGfP12Invert(t, x) 222 x = &gfP12{ 223 testdataP4, 224 testdataP4, 225 *(&gfP4{}).SetZero(), 226 } 227 testGfP12Invert(t, x) 228 x = &gfP12{ 229 testdataP4, 230 testdataP4, 231 testdataP4, 232 } 233 testGfP12Invert(t, x) 234 } 235 236 // Generate wToPMinus1 237 func Test_gfP12Frobenius_Case1(t *testing.T) { 238 expected := &gfP12{} 239 i := &gfP12{} 240 i.SetW() 241 pMinus1 := new(big.Int).Sub(p, big.NewInt(1)) 242 i.Exp(i, pMinus1) 243 i = gfP12Decode(i) 244 expected.z.x.SetZero() 245 expected.z.y.x.Set(zero) 246 expected.z.y.y.Set(fromBigInt(bigFromHex("3f23ea58e5720bdb843c6cfa9c08674947c5c86e0ddd04eda91d8354377b698b"))) 247 expected.x.SetZero() 248 expected.y.SetZero() 249 expected = gfP12Decode(expected) 250 if expected.x != i.x || expected.y != i.y || expected.z != i.z { 251 t.Errorf("got %v, expected %v", i, expected) 252 } 253 } 254 255 // Generate w2ToPMinus1 256 func Test_gfP12Frobenius_Case2(t *testing.T) { 257 expected := &gfP12{} 258 i := &gfP12{} 259 i.SetW2() 260 pMinus1 := new(big.Int).Sub(p, big.NewInt(1)) 261 i.Exp(i, pMinus1) 262 i = gfP12Decode(i) 263 expected.z.x.SetZero() 264 expected.z.y.x.Set(zero) 265 expected.z.y.y.Set(fromBigInt(bigFromHex("0000000000000000f300000002a3a6f2780272354f8b78f4d5fc11967be65334"))) 266 expected.x.SetZero() 267 expected.y.SetZero() 268 expected = gfP12Decode(expected) 269 if expected.x != i.x || expected.y != i.y || expected.z != i.z { 270 t.Errorf("got %v, expected %v", i, expected) 271 } 272 } 273 274 // Generate wToP2Minus1 275 func Test_gfP12FrobeniusP2_Case1(t *testing.T) { 276 expected := &gfP12{} 277 i := &gfP12{} 278 i.SetW() 279 p2 := new(big.Int).Mul(p, p) 280 p2 = new(big.Int).Sub(p2, big.NewInt(1)) 281 i.Exp(i, p2) 282 i = gfP12Decode(i) 283 expected.z.x.SetZero() 284 expected.z.y.x.Set(zero) 285 expected.z.y.y.Set(fromBigInt(bigFromHex("0000000000000000f300000002a3a6f2780272354f8b78f4d5fc11967be65334"))) 286 expected.x.SetZero() 287 expected.y.SetZero() 288 expected = gfP12Decode(expected) 289 if expected.x != i.x || expected.y != i.y || expected.z != i.z { 290 t.Errorf("got %v, expected %v", i, expected) 291 } 292 } 293 294 // Generate w2ToP2Minus1 295 func Test_gfP12FrobeniusP2_Case2(t *testing.T) { 296 expected := &gfP12{} 297 i := &gfP12{} 298 i.SetW2() 299 p2 := new(big.Int).Mul(p, p) 300 p2 = new(big.Int).Sub(p2, big.NewInt(1)) 301 i.Exp(i, p2) 302 i = gfP12Decode(i) 303 expected.z.x.SetZero() 304 expected.z.y.x.Set(zero) 305 expected.z.y.y.Set(fromBigInt(bigFromHex("0000000000000000f300000002a3a6f2780272354f8b78f4d5fc11967be65333"))) 306 expected.x.SetZero() 307 expected.y.SetZero() 308 expected = gfP12Decode(expected) 309 if expected.x != i.x || expected.y != i.y || expected.z != i.z { 310 t.Errorf("got %v, expected %v", i, expected) 311 } 312 } 313 314 // Generate wToP3Minus1 315 func Test_gfP12FrobeniusP3_Case1(t *testing.T) { 316 expected := &gfP12{} 317 i := &gfP12{} 318 i.SetW() 319 p3 := new(big.Int).Mul(p, p) 320 p3.Mul(p3, p) 321 p3 = new(big.Int).Sub(p3, big.NewInt(1)) 322 i.Exp(i, p3) 323 i = gfP12Decode(i) 324 expected.z.x.SetZero() 325 expected.z.y.x.Set(zero) 326 expected.z.y.y.Set(fromBigInt(bigFromHex("6c648de5dc0a3f2cf55acc93ee0baf159f9d411806dc5177f5b21fd3da24d011"))) 327 expected.x.SetZero() 328 expected.y.SetZero() 329 expected = gfP12Decode(expected) 330 if expected.x != i.x || expected.y != i.y || expected.z != i.z { 331 t.Errorf("got %v, expected %v", i, expected) 332 } 333 } 334 335 // Generate w2ToP3minus1 336 func Test_gfP12FrobeniusP3_Case2(t *testing.T) { 337 expected := &gfP12{} 338 i := &gfP12{} 339 i.SetW2() 340 p3 := new(big.Int).Mul(p, p) 341 p3.Mul(p3, p) 342 p3 = new(big.Int).Sub(p3, big.NewInt(1)) 343 i.Exp(i, p3) 344 i = gfP12Decode(i) 345 expected.z.x.SetZero() 346 expected.z.y.x.Set(zero) 347 expected.z.y.y.Set(fromBigInt(bigFromHex("b640000002a3a6f1d603ab4ff58ec74521f2934b1a7aeedbe56f9b27e351457c"))) // -1 348 expected.x.SetZero() 349 expected.y.SetZero() 350 expected = gfP12Decode(expected) 351 if expected.x != i.x || expected.y != i.y || expected.z != i.z { 352 t.Errorf("got %v, expected %v", i, expected) 353 } 354 } 355 356 func Test_gfP12Frobenius(t *testing.T) { 357 x := &gfP12{ 358 testdataP4, 359 testdataP4, 360 testdataP4, 361 } 362 expected := &gfP12{} 363 expected.Exp(x, p) 364 got := &gfP12{} 365 got.Frobenius(x) 366 if expected.x != got.x || expected.y != got.y || expected.z != got.z { 367 t.Errorf("got %v, expected %v", got, expected) 368 } 369 } 370 371 func Test_gfP12FrobeniusP2(t *testing.T) { 372 x := &gfP12{ 373 testdataP4, 374 testdataP4, 375 testdataP4, 376 } 377 expected := &gfP12{} 378 p2 := new(big.Int).Mul(p, p) 379 expected.Exp(x, p2) 380 got := &gfP12{} 381 got.FrobeniusP2(x) 382 if expected.x != got.x || expected.y != got.y || expected.z != got.z { 383 t.Errorf("got %v, expected %v", got, expected) 384 } 385 } 386 387 func Test_gfP12FrobeniusP3(t *testing.T) { 388 x := &gfP12{ 389 testdataP4, 390 testdataP4, 391 testdataP4, 392 } 393 expected := &gfP12{} 394 p3 := new(big.Int).Mul(p, p) 395 p3.Mul(p3, p) 396 expected.Exp(x, p3) 397 got := &gfP12{} 398 got.FrobeniusP3(x) 399 if expected.x != got.x || expected.y != got.y || expected.z != got.z { 400 t.Errorf("got %v, expected %v", got, expected) 401 } 402 } 403 404 func Test_gfP12FrobeniusP6(t *testing.T) { 405 x := &gfP12{ 406 testdataP4, 407 testdataP4, 408 testdataP4, 409 } 410 expected := &gfP12{} 411 p6 := new(big.Int).Mul(p, p) 412 p6.Mul(p6, p) 413 p6.Mul(p6, p6) 414 expected.Exp(x, p6) 415 got := &gfP12{} 416 got.FrobeniusP6(x) 417 if expected.x != got.x || expected.y != got.y || expected.z != got.z { 418 t.Errorf("got %v, expected %v", got, expected) 419 } 420 } 421 422 func Test_W3(t *testing.T) { 423 w1 := (&gfP12{}).SetW() 424 w2 := (&gfP12{}).SetW2() 425 426 w1.Mul(w2, w1) 427 w1 = gfP12Decode(w1) 428 gfp4zero := (&gfP4{}).SetZero() 429 gfp4v := (&gfP4{}).SetV() 430 gfp4v = gfP4Decode(gfp4v) 431 if w1.x != *gfp4zero || w1.y != *gfp4zero || w1.z != *gfp4v { 432 t.Errorf("not expected") 433 } 434 } 435 436 func BenchmarkGfP12Invert(b *testing.B) { 437 x := &gfP12{ 438 testdataP4, 439 testdataP4, 440 testdataP4, 441 } 442 got := &gfP12{} 443 b.ReportAllocs() 444 b.ResetTimer() 445 for i := 0; i < b.N; i++ { 446 got.Invert(x) 447 } 448 } 449 450 func BenchmarkGfP12Frobenius(b *testing.B) { 451 x := &gfP12{ 452 testdataP4, 453 testdataP4, 454 testdataP4, 455 } 456 expected := &gfP12{} 457 expected.Exp(x, p) 458 got := &gfP12{} 459 b.ReportAllocs() 460 b.ResetTimer() 461 for i := 0; i < b.N; i++ { 462 got.Frobenius(x) 463 if *expected != *got { 464 b.Errorf("got %v, expected %v", got, expected) 465 } 466 } 467 } 468 469 func BenchmarkGfP12Mul(b *testing.B) { 470 x := &gfP12{ 471 testdataP4, 472 testdataP4, 473 testdataP4, 474 } 475 got := &gfP12{} 476 b.ReportAllocs() 477 b.ResetTimer() 478 for i := 0; i < b.N; i++ { 479 got.Mul(x, x) 480 } 481 } 482 483 func BenchmarkGfP12Squre(b *testing.B) { 484 x := &gfP12{ 485 testdataP4, 486 testdataP4, 487 testdataP4, 488 } 489 got := &gfP12{} 490 b.ReportAllocs() 491 b.ResetTimer() 492 for i := 0; i < b.N; i++ { 493 got.Square(x) 494 } 495 } 496 497 func BenchmarkGfP12Squres(b *testing.B) { 498 x := &gfP12{ 499 testdataP4, 500 testdataP4, 501 testdataP4, 502 } 503 got := &gfP12{} 504 b.ReportAllocs() 505 b.ResetTimer() 506 for i := 0; i < b.N; i++ { 507 got.Squares(x, 61) 508 } 509 } 510 511 func BenchmarkGfP12ExpU(b *testing.B) { 512 x := &gfP12{ 513 testdataP4, 514 testdataP4, 515 testdataP4, 516 } 517 // This is the p^6-Frobenius 518 t1 := (&gfP12{}).FrobeniusP6(x) 519 520 inv := (&gfP12{}).Invert(x) 521 t1.Mul(t1, inv) 522 523 t2 := inv.FrobeniusP2(t1) // reuse inv 524 t1.Mul(t1, t2) // t1 = in ^ ((p^6 - 1) * (p^2 + 1)), the first two parts of the exponentiation 525 526 got := &gfP12{} 527 b.ReportAllocs() 528 b.ResetTimer() 529 for i := 0; i < b.N; i++ { 530 got.Cyclo6PowToU(t1) 531 got.Cyclo6PowToU(t1) 532 got.Cyclo6PowToU(t1) 533 } 534 } 535 536 func BenchmarkGfP12ExpU2(b *testing.B) { 537 x := &gfP12{ 538 testdataP4, 539 testdataP4, 540 testdataP4, 541 } 542 got := &gfP12{} 543 b.ReportAllocs() 544 b.ResetTimer() 545 for i := 0; i < b.N; i++ { 546 got.Exp(x, u) 547 got.Exp(x, u) 548 got.Exp(x, u) 549 } 550 }