github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/internal/fptower/e2_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 "crypto/rand" 21 "testing" 22 23 "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" 24 "github.com/leanovate/gopter" 25 "github.com/leanovate/gopter/prop" 26 ) 27 28 // ------------------------------------------------------------ 29 // tests 30 31 const ( 32 nbFuzzShort = 10 33 nbFuzz = 50 34 ) 35 36 func TestE2ReceiverIsOperand(t *testing.T) { 37 38 t.Parallel() 39 parameters := gopter.DefaultTestParameters() 40 if testing.Short() { 41 parameters.MinSuccessfulTests = nbFuzzShort 42 } else { 43 parameters.MinSuccessfulTests = nbFuzz 44 } 45 46 properties := gopter.NewProperties(parameters) 47 48 genA := GenE2() 49 genB := GenE2() 50 genfp := GenFp() 51 52 properties.Property("[BLS12-381] Having the receiver as operand (addition) should output the same result", prop.ForAll( 53 func(a, b *E2) bool { 54 var c, d E2 55 d.Set(a) 56 c.Add(a, b) 57 a.Add(a, b) 58 b.Add(&d, b) 59 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 60 }, 61 genA, 62 genB, 63 )) 64 65 properties.Property("[BLS12-381] Having the receiver as operand (sub) should output the same result", prop.ForAll( 66 func(a, b *E2) bool { 67 var c, d E2 68 d.Set(a) 69 c.Sub(a, b) 70 a.Sub(a, b) 71 b.Sub(&d, b) 72 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 73 }, 74 genA, 75 genB, 76 )) 77 78 properties.Property("[BLS12-381] Having the receiver as operand (mul) should output the same result", prop.ForAll( 79 func(a, b *E2) bool { 80 var c, d E2 81 d.Set(a) 82 c.Mul(a, b) 83 a.Mul(a, b) 84 b.Mul(&d, b) 85 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 86 }, 87 genA, 88 genB, 89 )) 90 91 properties.Property("[BLS12-381] Having the receiver as operand (square) should output the same result", prop.ForAll( 92 func(a *E2) bool { 93 var b E2 94 b.Square(a) 95 a.Square(a) 96 return a.Equal(&b) 97 }, 98 genA, 99 )) 100 101 properties.Property("[BLS12-381] Having the receiver as operand (neg) should output the same result", prop.ForAll( 102 func(a *E2) bool { 103 var b E2 104 b.Neg(a) 105 a.Neg(a) 106 return a.Equal(&b) 107 }, 108 genA, 109 )) 110 111 properties.Property("[BLS12-381] Having the receiver as operand (double) should output the same result", prop.ForAll( 112 func(a *E2) bool { 113 var b E2 114 b.Double(a) 115 a.Double(a) 116 return a.Equal(&b) 117 }, 118 genA, 119 )) 120 121 properties.Property("[BLS12-381] Having the receiver as operand (mul by non residue) should output the same result", prop.ForAll( 122 func(a *E2) bool { 123 var b E2 124 b.MulByNonResidue(a) 125 a.MulByNonResidue(a) 126 return a.Equal(&b) 127 }, 128 genA, 129 )) 130 131 properties.Property("[BLS12-381] Having the receiver as operand (mul by non residue inverse) should output the same result", prop.ForAll( 132 func(a *E2) bool { 133 var b E2 134 b.MulByNonResidueInv(a) 135 a.MulByNonResidueInv(a) 136 return a.Equal(&b) 137 }, 138 genA, 139 )) 140 141 properties.Property("[BLS12-381] Having the receiver as operand (Inverse) should output the same result", prop.ForAll( 142 func(a *E2) bool { 143 var b E2 144 b.Inverse(a) 145 a.Inverse(a) 146 return a.Equal(&b) 147 }, 148 genA, 149 )) 150 151 properties.Property("[BLS12-381] Having the receiver as operand (Conjugate) should output the same result", prop.ForAll( 152 func(a *E2) bool { 153 var b E2 154 b.Conjugate(a) 155 a.Conjugate(a) 156 return a.Equal(&b) 157 }, 158 genA, 159 )) 160 161 properties.Property("[BLS12-381] Having the receiver as operand (mul by element) should output the same result", prop.ForAll( 162 func(a *E2, b fp.Element) bool { 163 var c E2 164 c.MulByElement(a, &b) 165 a.MulByElement(a, &b) 166 return a.Equal(&c) 167 }, 168 genA, 169 genfp, 170 )) 171 172 properties.Property("[BLS12-381] Having the receiver as operand (Sqrt) should output the same result", prop.ForAll( 173 func(a *E2) bool { 174 var b, c, d, s E2 175 176 s.Square(a) 177 a.Set(&s) 178 b.Set(&s) 179 180 a.Sqrt(a) 181 b.Sqrt(&b) 182 183 c.Square(a) 184 d.Square(&b) 185 return c.Equal(&d) 186 }, 187 genA, 188 )) 189 190 properties.TestingRun(t, gopter.ConsoleReporter(false)) 191 192 } 193 194 func TestE2MulMaxed(t *testing.T) { 195 // let's pick a and b, with maxed A0 and A1 196 var a, b E2 197 fpMaxValue := fp.Element{ 198 13402431016077863595, 199 2210141511517208575, 200 7435674573564081700, 201 7239337960414712511, 202 5412103778470702295, 203 1873798617647539866, 204 } 205 fpMaxValue[0]-- 206 207 a.A0 = fpMaxValue 208 a.A1 = fpMaxValue 209 b.A0 = fpMaxValue 210 b.A1 = fpMaxValue 211 212 var c, d E2 213 d.Inverse(&b) 214 c.Set(&a) 215 c.Mul(&c, &b).Mul(&c, &d) 216 if !c.Equal(&a) { 217 t.Fatal("mul with max fp failed") 218 } 219 } 220 221 func TestE2Ops(t *testing.T) { 222 223 t.Parallel() 224 parameters := gopter.DefaultTestParameters() 225 if testing.Short() { 226 parameters.MinSuccessfulTests = nbFuzzShort 227 } else { 228 parameters.MinSuccessfulTests = nbFuzz 229 } 230 231 properties := gopter.NewProperties(parameters) 232 233 genA := GenE2() 234 genB := GenE2() 235 genfp := GenFp() 236 237 properties.Property("[BLS12-381] sub & add should leave an element invariant", prop.ForAll( 238 func(a, b *E2) bool { 239 var c E2 240 c.Set(a) 241 c.Add(&c, b).Sub(&c, b) 242 return c.Equal(a) 243 }, 244 genA, 245 genB, 246 )) 247 248 properties.Property("[BLS12-381] mul & inverse should leave an element invariant", prop.ForAll( 249 func(a, b *E2) bool { 250 var c, d E2 251 d.Inverse(b) 252 c.Set(a) 253 c.Mul(&c, b).Mul(&c, &d) 254 return c.Equal(a) 255 }, 256 genA, 257 genB, 258 )) 259 260 properties.Property("[BLS12-381] BatchInvertE2 should output the same result as Inverse", prop.ForAll( 261 func(a, b, c *E2) bool { 262 263 batch := BatchInvertE2([]E2{*a, *b, *c}) 264 a.Inverse(a) 265 b.Inverse(b) 266 c.Inverse(c) 267 return a.Equal(&batch[0]) && b.Equal(&batch[1]) && c.Equal(&batch[2]) 268 }, 269 genA, 270 genA, 271 genA, 272 )) 273 274 properties.Property("[BLS12-381] mulGeneric & mul should be equal", prop.ForAll( 275 func(a, b *E2) bool { 276 var c, d E2 277 mulGenericE2(&c, a, b) 278 d.Mul(a, b) 279 return d.Equal(&c) 280 }, 281 genA, 282 genB, 283 )) 284 285 properties.Property("[BLS12-381] inverse twice should leave an element invariant", prop.ForAll( 286 func(a *E2) bool { 287 var b E2 288 b.Inverse(a).Inverse(&b) 289 return a.Equal(&b) 290 }, 291 genA, 292 )) 293 294 properties.Property("[BLS12-381] neg twice should leave an element invariant", prop.ForAll( 295 func(a *E2) bool { 296 var b E2 297 b.Neg(a).Neg(&b) 298 return a.Equal(&b) 299 }, 300 genA, 301 )) 302 303 properties.Property("[BLS12-381] square and mul should output the same result", prop.ForAll( 304 func(a *E2) bool { 305 var b, c E2 306 b.Mul(a, a) 307 c.Square(a) 308 return b.Equal(&c) 309 }, 310 genA, 311 )) 312 313 properties.Property("[BLS12-381] MulByElement MulByElement inverse should leave an element invariant", prop.ForAll( 314 func(a *E2, b fp.Element) bool { 315 var c E2 316 var d fp.Element 317 d.Inverse(&b) 318 c.MulByElement(a, &b).MulByElement(&c, &d) 319 return c.Equal(a) 320 }, 321 genA, 322 genfp, 323 )) 324 325 properties.Property("[BLS12-381] Double and mul by 2 should output the same result", prop.ForAll( 326 func(a *E2) bool { 327 var b E2 328 var c fp.Element 329 c.SetUint64(2) 330 b.Double(a) 331 a.MulByElement(a, &c) 332 return a.Equal(&b) 333 }, 334 genA, 335 )) 336 337 properties.Property("[BLS12-381] Mulbynonres mulbynonresinv should leave the element invariant", prop.ForAll( 338 func(a *E2) bool { 339 var b E2 340 b.MulByNonResidue(a).MulByNonResidueInv(&b) 341 return a.Equal(&b) 342 }, 343 genA, 344 )) 345 346 properties.Property("[BLS12-381] a + pi(a), a-pi(a) should be real", prop.ForAll( 347 func(a *E2) bool { 348 var b, c, d E2 349 var e, f fp.Element 350 b.Conjugate(a) 351 c.Add(a, &b) 352 d.Sub(a, &b) 353 e.Double(&a.A0) 354 f.Double(&a.A1) 355 return c.A1.IsZero() && d.A0.IsZero() && e.Equal(&c.A0) && f.Equal(&d.A1) 356 }, 357 genA, 358 )) 359 360 properties.Property("[BLS12-381] Legendre on square should output 1", prop.ForAll( 361 func(a *E2) bool { 362 var b E2 363 b.Square(a) 364 c := b.Legendre() 365 return c == 1 366 }, 367 genA, 368 )) 369 370 properties.Property("[BLS12-381] square(sqrt) should leave an element invariant", prop.ForAll( 371 func(a *E2) bool { 372 var b, c, d, e E2 373 b.Square(a) 374 c.Sqrt(&b) 375 d.Square(&c) 376 e.Neg(a) 377 return (c.Equal(a) || c.Equal(&e)) && d.Equal(&b) 378 }, 379 genA, 380 )) 381 382 properties.Property("[BLS12-381] neg(E2) == neg(E2.A0, E2.A1)", prop.ForAll( 383 func(a *E2) bool { 384 var b, c E2 385 b.Neg(a) 386 c.A0.Neg(&a.A0) 387 c.A1.Neg(&a.A1) 388 return c.Equal(&b) 389 }, 390 genA, 391 )) 392 393 properties.Property("[BLS12-381] Cmp and LexicographicallyLargest should be consistent", prop.ForAll( 394 func(a *E2) bool { 395 var negA E2 396 negA.Neg(a) 397 cmpResult := a.Cmp(&negA) 398 lResult := a.LexicographicallyLargest() 399 if lResult && cmpResult == 1 { 400 return true 401 } 402 if !lResult && cmpResult != 1 { 403 return true 404 } 405 return false 406 }, 407 genA, 408 )) 409 410 properties.TestingRun(t, gopter.ConsoleReporter(false)) 411 412 } 413 414 // ------------------------------------------------------------ 415 // benches 416 417 func BenchmarkE2Add(b *testing.B) { 418 var a, c E2 419 _, _ = a.SetRandom() 420 _, _ = c.SetRandom() 421 b.ResetTimer() 422 for i := 0; i < b.N; i++ { 423 a.Add(&a, &c) 424 } 425 } 426 427 func BenchmarkE2Sub(b *testing.B) { 428 var a, c E2 429 _, _ = a.SetRandom() 430 _, _ = c.SetRandom() 431 b.ResetTimer() 432 for i := 0; i < b.N; i++ { 433 a.Sub(&a, &c) 434 } 435 } 436 437 func BenchmarkE2Mul(b *testing.B) { 438 var a, c E2 439 _, _ = a.SetRandom() 440 _, _ = c.SetRandom() 441 b.ResetTimer() 442 for i := 0; i < b.N; i++ { 443 a.Mul(&a, &c) 444 } 445 } 446 447 func BenchmarkE2MulByElement(b *testing.B) { 448 var a E2 449 var c fp.Element 450 _, _ = c.SetRandom() 451 _, _ = a.SetRandom() 452 b.ResetTimer() 453 for i := 0; i < b.N; i++ { 454 a.MulByElement(&a, &c) 455 } 456 } 457 458 func BenchmarkE2Square(b *testing.B) { 459 var a E2 460 _, _ = a.SetRandom() 461 b.ResetTimer() 462 for i := 0; i < b.N; i++ { 463 a.Square(&a) 464 } 465 } 466 467 func BenchmarkE2Sqrt(b *testing.B) { 468 var a E2 469 _, _ = a.SetRandom() 470 b.ResetTimer() 471 for i := 0; i < b.N; i++ { 472 a.Sqrt(&a) 473 } 474 } 475 476 func BenchmarkE2Exp(b *testing.B) { 477 var x E2 478 _, _ = x.SetRandom() 479 b1, _ := rand.Int(rand.Reader, fp.Modulus()) 480 b.ResetTimer() 481 for i := 0; i < b.N; i++ { 482 x.Exp(x, b1) 483 } 484 } 485 486 func BenchmarkE2Inverse(b *testing.B) { 487 var a E2 488 _, _ = a.SetRandom() 489 b.ResetTimer() 490 for i := 0; i < b.N; i++ { 491 a.Inverse(&a) 492 } 493 } 494 495 func BenchmarkE2MulNonRes(b *testing.B) { 496 var a E2 497 _, _ = a.SetRandom() 498 b.ResetTimer() 499 for i := 0; i < b.N; i++ { 500 a.MulByNonResidue(&a) 501 } 502 } 503 504 func BenchmarkE2MulNonResInv(b *testing.B) { 505 var a E2 506 _, _ = a.SetRandom() 507 b.ResetTimer() 508 for i := 0; i < b.N; i++ { 509 a.MulByNonResidueInv(&a) 510 } 511 } 512 513 func BenchmarkE2Conjugate(b *testing.B) { 514 var a E2 515 _, _ = a.SetRandom() 516 b.ResetTimer() 517 for i := 0; i < b.N; i++ { 518 a.Conjugate(&a) 519 } 520 } 521 522 func TestE2Div(t *testing.T) { 523 524 parameters := gopter.DefaultTestParameters() 525 properties := gopter.NewProperties(parameters) 526 527 genA := GenE2() 528 genB := GenE2() 529 530 properties.Property("[BLS12-381] dividing then multiplying by the same element does nothing", prop.ForAll( 531 func(a, b *E2) bool { 532 var c E2 533 c.Div(a, b) 534 c.Mul(&c, b) 535 return c.Equal(a) 536 }, 537 genA, 538 genB, 539 )) 540 541 properties.TestingRun(t, gopter.ConsoleReporter(false)) 542 }