github.com/consensys/gnark-crypto@v0.14.0/internal/generator/tower/template/fq12over6over2/tests/fq12.go.tmpl (about) 1 {{$Name := .Curve.Name}} 2 import ( 3 "math/big" 4 "testing" 5 6 "github.com/consensys/gnark-crypto/ecc/{{$Name}}/fp" 7 "github.com/leanovate/gopter" 8 "github.com/leanovate/gopter/prop" 9 ) 10 11 // ------------------------------------------------------------ 12 // tests 13 14 func TestE12Serialization(t *testing.T) { 15 16 t.Parallel() 17 parameters := gopter.DefaultTestParameters() 18 if testing.Short() { 19 parameters.MinSuccessfulTests = nbFuzzShort 20 } else { 21 parameters.MinSuccessfulTests = nbFuzz 22 } 23 24 properties := gopter.NewProperties(parameters) 25 26 genA := GenE12() 27 28 properties.Property("[{{ toUpper $Name}}] SetBytes(Bytes()) should stay constant", prop.ForAll( 29 func(a *E12) bool { 30 var b E12 31 buf := a.Bytes() 32 if err := b.SetBytes(buf[:]); err != nil { 33 return false 34 } 35 return a.Equal(&b) 36 }, 37 genA, 38 )) 39 40 properties.TestingRun(t, gopter.ConsoleReporter(false)) 41 } 42 43 func TestE12ReceiverIsOperand(t *testing.T) { 44 45 parameters := gopter.DefaultTestParameters() 46 if testing.Short() { 47 parameters.MinSuccessfulTests = nbFuzzShort 48 } else { 49 parameters.MinSuccessfulTests = nbFuzz 50 } 51 52 properties := gopter.NewProperties(parameters) 53 54 genA := GenE12() 55 genB := GenE12() 56 57 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (addition) should output the same result", prop.ForAll( 58 func(a, b *E12) bool { 59 var c, d E12 60 d.Set(a) 61 c.Add(a, b) 62 a.Add(a, b) 63 b.Add(&d, b) 64 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 65 }, 66 genA, 67 genB, 68 )) 69 70 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (sub) should output the same result", prop.ForAll( 71 func(a, b *E12) bool { 72 var c, d E12 73 d.Set(a) 74 c.Sub(a, b) 75 a.Sub(a, b) 76 b.Sub(&d, b) 77 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 78 }, 79 genA, 80 genB, 81 )) 82 83 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (mul) should output the same result", prop.ForAll( 84 func(a, b *E12) bool { 85 var c, d E12 86 d.Set(a) 87 c.Mul(a, b) 88 a.Mul(a, b) 89 b.Mul(&d, b) 90 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 91 }, 92 genA, 93 genB, 94 )) 95 96 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (square) should output the same result", prop.ForAll( 97 func(a *E12) bool { 98 var b E12 99 b.Square(a) 100 a.Square(a) 101 return a.Equal(&b) 102 }, 103 genA, 104 )) 105 106 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (double) should output the same result", prop.ForAll( 107 func(a *E12) bool { 108 var b E12 109 b.Double(a) 110 a.Double(a) 111 return a.Equal(&b) 112 }, 113 genA, 114 )) 115 116 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Inverse) should output the same result", prop.ForAll( 117 func(a *E12) bool { 118 var b E12 119 b.Inverse(a) 120 a.Inverse(a) 121 return a.Equal(&b) 122 }, 123 genA, 124 )) 125 126 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Cyclotomic square) should output the same result", prop.ForAll( 127 func(a *E12) bool { 128 var b E12 129 b.CyclotomicSquare(a) 130 a.CyclotomicSquare(a) 131 return a.Equal(&b) 132 }, 133 genA, 134 )) 135 136 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Conjugate) should output the same result", prop.ForAll( 137 func(a *E12) bool { 138 var b E12 139 b.Conjugate(a) 140 a.Conjugate(a) 141 return a.Equal(&b) 142 }, 143 genA, 144 )) 145 146 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Frobenius) should output the same result", prop.ForAll( 147 func(a *E12) bool { 148 var b E12 149 b.Frobenius(a) 150 a.Frobenius(a) 151 return a.Equal(&b) 152 }, 153 genA, 154 )) 155 156 properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (FrobeniusSquare) should output the same result", prop.ForAll( 157 func(a *E12) bool { 158 var b E12 159 b.FrobeniusSquare(a) 160 a.FrobeniusSquare(a) 161 return a.Equal(&b) 162 }, 163 genA, 164 )) 165 166 properties.TestingRun(t, gopter.ConsoleReporter(false)) 167 } 168 169 func TestE12Ops(t *testing.T) { 170 171 parameters := gopter.DefaultTestParameters() 172 if testing.Short() { 173 parameters.MinSuccessfulTests = nbFuzzShort 174 } else { 175 parameters.MinSuccessfulTests = nbFuzz 176 } 177 178 properties := gopter.NewProperties(parameters) 179 180 181 182 genA := GenE12() 183 genB := GenE12() 184 genExp := GenFp() 185 186 properties.Property("[{{ toUpper $Name }}] sub & add should leave an element invariant", prop.ForAll( 187 func(a, b *E12) bool { 188 var c E12 189 c.Set(a) 190 c.Add(&c, b).Sub(&c, b) 191 return c.Equal(a) 192 }, 193 genA, 194 genB, 195 )) 196 197 properties.Property("[{{ toUpper $Name }}] mul & inverse should leave an element invariant", prop.ForAll( 198 func(a, b *E12) bool { 199 var c, d E12 200 d.Inverse(b) 201 c.Set(a) 202 c.Mul(&c, b).Mul(&c, &d) 203 return c.Equal(a) 204 }, 205 genA, 206 genB, 207 )) 208 209 properties.Property("[{{ toUpper $Name }}] inverse twice should leave an element invariant", prop.ForAll( 210 func(a *E12) bool { 211 var b E12 212 b.Inverse(a).Inverse(&b) 213 return a.Equal(&b) 214 }, 215 genA, 216 )) 217 218 properties.Property("[{{ toUpper $Name }}] square and mul should output the same result", prop.ForAll( 219 func(a *E12) bool { 220 var b, c E12 221 b.Mul(a, a) 222 c.Square(a) 223 return b.Equal(&c) 224 }, 225 genA, 226 )) 227 228 properties.Property("[{{ toUpper $Name }}] a + pi(a), a-pi(a) should be real", prop.ForAll( 229 func(a *E12) bool { 230 var b, c, d E12 231 var e, f, g E6 232 b.Conjugate(a) 233 c.Add(a, &b) 234 d.Sub(a, &b) 235 e.Double(&a.C0) 236 f.Double(&a.C1) 237 return c.C1.Equal(&g) && d.C0.Equal(&g) && e.Equal(&c.C0) && f.Equal(&d.C1) 238 }, 239 genA, 240 )) 241 242 properties.Property("[{{ toUpper $Name }}] Torus-based Compress/decompress E12 elements in the cyclotomic subgroup", prop.ForAll( 243 func(a *E12) bool { 244 var b E12 245 b.Conjugate(a) 246 a.Inverse(a) 247 b.Mul(&b, a) 248 a.FrobeniusSquare(&b).Mul(a, &b) 249 250 c, _ := a.CompressTorus() 251 d := c.DecompressTorus() 252 return a.Equal(&d) 253 }, 254 genA, 255 )) 256 257 properties.Property("[{{ toUpper $Name }}] Torus-based batch Compress/decompress E12 elements in the cyclotomic subgroup", prop.ForAll( 258 func(a, e, f *E12) bool { 259 var b E12 260 b.Conjugate(a) 261 a.Inverse(a) 262 b.Mul(&b, a) 263 a.FrobeniusSquare(&b).Mul(a, &b) 264 265 e.CyclotomicSquare(a) 266 f.CyclotomicSquare(e) 267 268 c, _ := BatchCompressTorus([]E12{*a, *e, *f}) 269 d, _ := BatchDecompressTorus(c) 270 return a.Equal(&d[0]) && e.Equal(&d[1]) && f.Equal(&d[2]) 271 }, 272 genA, 273 genA, 274 genA, 275 )) 276 277 properties.Property("[{{ toUpper $Name }}] pi**12=id", prop.ForAll( 278 func(a *E12) bool { 279 var b E12 280 b.Frobenius(a). 281 Frobenius(&b). 282 Frobenius(&b). 283 Frobenius(&b). 284 Frobenius(&b). 285 Frobenius(&b). 286 Frobenius(&b). 287 Frobenius(&b). 288 Frobenius(&b). 289 Frobenius(&b). 290 Frobenius(&b). 291 Frobenius(&b) 292 return b.Equal(a) 293 }, 294 genA, 295 )) 296 297 properties.Property("[{{ toUpper $Name }}] (pi**2)**6=id", prop.ForAll( 298 func(a *E12) bool { 299 var b E12 300 b.FrobeniusSquare(a). 301 FrobeniusSquare(&b). 302 FrobeniusSquare(&b). 303 FrobeniusSquare(&b). 304 FrobeniusSquare(&b). 305 FrobeniusSquare(&b) 306 return b.Equal(a) 307 }, 308 genA, 309 )) 310 311 properties.Property("[{{ toUpper $Name }}] cyclotomic square (Granger-Scott) and square should be the same in the cyclotomic subgroup", prop.ForAll( 312 func(a *E12) bool { 313 var b, c, d E12 314 b.Conjugate(a) 315 a.Inverse(a) 316 b.Mul(&b, a) 317 a.FrobeniusSquare(&b).Mul(a, &b) 318 c.Square(a) 319 d.CyclotomicSquare(a) 320 return c.Equal(&d) 321 }, 322 genA, 323 )) 324 325 properties.Property("[{{ toUpper $Name }}] compressed cyclotomic square (Karabina) and square should be the same in the cyclotomic subgroup", prop.ForAll( 326 func(a *E12) bool { 327 var _a, b, c, d, _c, _d E12 328 _a.SetOne().Double(&_a) 329 330 // put a and _a in the cyclotomic subgroup 331 // a (g3 != 0 probably) 332 b.Conjugate(a) 333 a.Inverse(a) 334 b.Mul(&b, a) 335 a.FrobeniusSquare(&b).Mul(a, &b) 336 // _a (g3 == 0) 337 b.Conjugate(&_a) 338 _a.Inverse(&_a) 339 b.Mul(&b, &_a) 340 _a.FrobeniusSquare(&b).Mul(&_a, &b) 341 342 // case g3 != 0 343 c.Square(a) 344 d.CyclotomicSquareCompressed(a).DecompressKarabina(&d) 345 346 // case g3 == 0 347 _c.Square(&_a) 348 _d.CyclotomicSquareCompressed(&_a).DecompressKarabina(&_d) 349 350 return c.Equal(&d) 351 }, 352 genA, 353 )) 354 355 properties.Property("[{{ toUpper $Name }}] batch decompress and individual decompress (Karabina) should be the same", prop.ForAll( 356 func(a *E12) bool { 357 var _a, b E12 358 _a.SetOne().Double(&_a) 359 360 // put a and _a in the cyclotomic subgroup 361 // a (g3 !=0 probably) 362 b.Conjugate(a) 363 a.Inverse(a) 364 b.Mul(&b, a) 365 a.FrobeniusSquare(&b).Mul(a, &b) 366 // _a (g3 == 0) 367 b.Conjugate(&_a) 368 _a.Inverse(&_a) 369 b.Mul(&b, &_a) 370 _a.FrobeniusSquare(&b).Mul(&_a, &b) 371 372 var a2, a4, a17 E12 373 a2.Set(&_a) 374 a4.Set(a) 375 a17.Set(a) 376 a2.nSquareCompressed(2) // case g3 == 0 377 a4.nSquareCompressed(4) 378 a17.nSquareCompressed(17) 379 batch := BatchDecompressKarabina([]E12{a2, a4, a17}) 380 a2.DecompressKarabina(&a2) 381 a4.DecompressKarabina(&a4) 382 a17.DecompressKarabina(&a17) 383 384 return a2.Equal(&batch[0]) && a4.Equal(&batch[1]) && a17.Equal(&batch[2]) 385 }, 386 genA, 387 )) 388 389 properties.Property("[{{ toUpper $Name }}] Exp and CyclotomicExp results must be the same in the cyclotomic subgroup", prop.ForAll( 390 func(a *E12, e fp.Element) bool { 391 var b, c, d E12 392 // put in the cyclo subgroup 393 b.Conjugate(a) 394 a.Inverse(a) 395 b.Mul(&b, a) 396 a.FrobeniusSquare(&b).Mul(a, &b) 397 398 var _e big.Int 399 k := new(big.Int).SetUint64(12) 400 e.Exp(e, k) 401 e.BigInt(&_e) 402 403 c.Exp(*a, &_e) 404 d.CyclotomicExp(*a, &_e) 405 406 return c.Equal(&d) 407 }, 408 genA, 409 genExp, 410 )) 411 412 properties.Property("[{{ toUpper $Name }}] Frobenius of x in E12 should be equal to x^q", prop.ForAll( 413 func(a *E12) bool { 414 var b, c E12 415 q := fp.Modulus() 416 b.Frobenius(a) 417 c.Exp(*a, q) 418 return c.Equal(&b) 419 }, 420 genA, 421 )) 422 423 properties.Property("[{{ toUpper $Name }}] FrobeniusSquare of x in E12 should be equal to x^(q^2)", prop.ForAll( 424 func(a *E12) bool { 425 var b, c E12 426 q := fp.Modulus() 427 b.FrobeniusSquare(a) 428 c.Exp(*a, q).Exp(c, q) 429 return c.Equal(&b) 430 }, 431 genA, 432 )) 433 434 properties.TestingRun(t, gopter.ConsoleReporter(false)) 435 436 } 437 438 // ------------------------------------------------------------ 439 // benches 440 441 func BenchmarkE12Add(b *testing.B) { 442 var a, c E12 443 _,_ = a.SetRandom() 444 _,_ = c.SetRandom() 445 b.ResetTimer() 446 for i := 0; i < b.N; i++ { 447 a.Add(&a, &c) 448 } 449 } 450 451 func BenchmarkE12Sub(b *testing.B) { 452 var a, c E12 453 _,_ = a.SetRandom() 454 _,_ = c.SetRandom() 455 b.ResetTimer() 456 for i := 0; i < b.N; i++ { 457 a.Sub(&a, &c) 458 } 459 } 460 461 func BenchmarkE12Mul(b *testing.B) { 462 var a, c E12 463 _,_ = a.SetRandom() 464 _,_ = c.SetRandom() 465 b.ResetTimer() 466 for i := 0; i < b.N; i++ { 467 a.Mul(&a, &c) 468 } 469 } 470 471 func BenchmarkE12Cyclosquare(b *testing.B) { 472 var a E12 473 _,_ = a.SetRandom() 474 b.ResetTimer() 475 for i := 0; i < b.N; i++ { 476 a.CyclotomicSquare(&a) 477 } 478 } 479 480 func BenchmarkE12Square(b *testing.B) { 481 var a E12 482 _,_ = a.SetRandom() 483 b.ResetTimer() 484 for i := 0; i < b.N; i++ { 485 a.Square(&a) 486 } 487 } 488 489 func BenchmarkE12Inverse(b *testing.B) { 490 var a E12 491 _,_ = a.SetRandom() 492 b.ResetTimer() 493 for i := 0; i < b.N; i++ { 494 a.Inverse(&a) 495 } 496 } 497 498 func BenchmarkE12Conjugate(b *testing.B) { 499 var a E12 500 _,_ = a.SetRandom() 501 b.ResetTimer() 502 for i := 0; i < b.N; i++ { 503 a.Conjugate(&a) 504 } 505 } 506 507 func BenchmarkE12Frobenius(b *testing.B) { 508 var a E12 509 _,_ = a.SetRandom() 510 b.ResetTimer() 511 for i := 0; i < b.N; i++ { 512 a.Frobenius(&a) 513 } 514 } 515 516 func BenchmarkE12FrobeniusSquare(b *testing.B) { 517 var a E12 518 _,_ = a.SetRandom() 519 b.ResetTimer() 520 for i := 0; i < b.N; i++ { 521 a.FrobeniusSquare(&a) 522 } 523 } 524 525 func BenchmarkE12Expt(b *testing.B) { 526 var a E12 527 _,_ = a.SetRandom() 528 b.ResetTimer() 529 for i := 0; i < b.N; i++ { 530 a.Expt(&a) 531 } 532 } 533 534 {{ template "base" .}}