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