github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/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-377/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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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-377] 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 9586122913090633729, 199 1660523435060625408, 200 2230234197602682880, 201 1883307231910630287, 202 14284016967150029115, 203 121098312706494698, 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-377] 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-377] 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-377] 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-377] inverse twice should leave an element invariant", prop.ForAll( 275 func(a *E2) bool { 276 var b E2 277 b.Inverse(a).Inverse(&b) 278 return a.Equal(&b) 279 }, 280 genA, 281 )) 282 283 properties.Property("[BLS12-377] neg twice should leave an element invariant", prop.ForAll( 284 func(a *E2) bool { 285 var b E2 286 b.Neg(a).Neg(&b) 287 return a.Equal(&b) 288 }, 289 genA, 290 )) 291 292 properties.Property("[BLS12-377] square and mul should output the same result", prop.ForAll( 293 func(a *E2) bool { 294 var b, c E2 295 b.Mul(a, a) 296 c.Square(a) 297 return b.Equal(&c) 298 }, 299 genA, 300 )) 301 302 properties.Property("[BLS12-377] MulByElement MulByElement inverse should leave an element invariant", prop.ForAll( 303 func(a *E2, b fp.Element) bool { 304 var c E2 305 var d fp.Element 306 d.Inverse(&b) 307 c.MulByElement(a, &b).MulByElement(&c, &d) 308 return c.Equal(a) 309 }, 310 genA, 311 genfp, 312 )) 313 314 properties.Property("[BLS12-377] Double and mul by 2 should output the same result", prop.ForAll( 315 func(a *E2) bool { 316 var b E2 317 var c fp.Element 318 c.SetUint64(2) 319 b.Double(a) 320 a.MulByElement(a, &c) 321 return a.Equal(&b) 322 }, 323 genA, 324 )) 325 326 properties.Property("[BLS12-377] Mulbynonres mulbynonresinv should leave the element invariant", prop.ForAll( 327 func(a *E2) bool { 328 var b E2 329 b.MulByNonResidue(a).MulByNonResidueInv(&b) 330 return a.Equal(&b) 331 }, 332 genA, 333 )) 334 335 properties.Property("[BLS12-377] a + pi(a), a-pi(a) should be real", prop.ForAll( 336 func(a *E2) bool { 337 var b, c, d E2 338 var e, f fp.Element 339 b.Conjugate(a) 340 c.Add(a, &b) 341 d.Sub(a, &b) 342 e.Double(&a.A0) 343 f.Double(&a.A1) 344 return c.A1.IsZero() && d.A0.IsZero() && e.Equal(&c.A0) && f.Equal(&d.A1) 345 }, 346 genA, 347 )) 348 349 properties.Property("[BLS12-377] Legendre on square should output 1", prop.ForAll( 350 func(a *E2) bool { 351 var b E2 352 b.Square(a) 353 c := b.Legendre() 354 return c == 1 355 }, 356 genA, 357 )) 358 359 properties.Property("[BLS12-377] square(sqrt) should leave an element invariant", prop.ForAll( 360 func(a *E2) bool { 361 var b, c, d, e E2 362 b.Square(a) 363 c.Sqrt(&b) 364 d.Square(&c) 365 e.Neg(a) 366 return (c.Equal(a) || c.Equal(&e)) && d.Equal(&b) 367 }, 368 genA, 369 )) 370 371 properties.Property("[BLS12-377] neg(E2) == neg(E2.A0, E2.A1)", prop.ForAll( 372 func(a *E2) bool { 373 var b, c E2 374 b.Neg(a) 375 c.A0.Neg(&a.A0) 376 c.A1.Neg(&a.A1) 377 return c.Equal(&b) 378 }, 379 genA, 380 )) 381 382 properties.Property("[BLS12-377] Cmp and LexicographicallyLargest should be consistent", prop.ForAll( 383 func(a *E2) bool { 384 var negA E2 385 negA.Neg(a) 386 cmpResult := a.Cmp(&negA) 387 lResult := a.LexicographicallyLargest() 388 if lResult && cmpResult == 1 { 389 return true 390 } 391 if !lResult && cmpResult != 1 { 392 return true 393 } 394 return false 395 }, 396 genA, 397 )) 398 399 properties.TestingRun(t, gopter.ConsoleReporter(false)) 400 401 } 402 403 // ------------------------------------------------------------ 404 // benches 405 406 func BenchmarkE2Add(b *testing.B) { 407 var a, c E2 408 _, _ = a.SetRandom() 409 _, _ = c.SetRandom() 410 b.ResetTimer() 411 for i := 0; i < b.N; i++ { 412 a.Add(&a, &c) 413 } 414 } 415 416 func BenchmarkE2Sub(b *testing.B) { 417 var a, c E2 418 _, _ = a.SetRandom() 419 _, _ = c.SetRandom() 420 b.ResetTimer() 421 for i := 0; i < b.N; i++ { 422 a.Sub(&a, &c) 423 } 424 } 425 426 func BenchmarkE2Mul(b *testing.B) { 427 var a, c E2 428 _, _ = a.SetRandom() 429 _, _ = c.SetRandom() 430 b.ResetTimer() 431 for i := 0; i < b.N; i++ { 432 a.Mul(&a, &c) 433 } 434 } 435 436 func BenchmarkE2MulByElement(b *testing.B) { 437 var a E2 438 var c fp.Element 439 _, _ = c.SetRandom() 440 _, _ = a.SetRandom() 441 b.ResetTimer() 442 for i := 0; i < b.N; i++ { 443 a.MulByElement(&a, &c) 444 } 445 } 446 447 func BenchmarkE2Square(b *testing.B) { 448 var a E2 449 _, _ = a.SetRandom() 450 b.ResetTimer() 451 for i := 0; i < b.N; i++ { 452 a.Square(&a) 453 } 454 } 455 456 func BenchmarkE2Sqrt(b *testing.B) { 457 var a E2 458 _, _ = a.SetRandom() 459 b.ResetTimer() 460 for i := 0; i < b.N; i++ { 461 a.Sqrt(&a) 462 } 463 } 464 465 func BenchmarkE2Exp(b *testing.B) { 466 var x E2 467 _, _ = x.SetRandom() 468 b1, _ := rand.Int(rand.Reader, fp.Modulus()) 469 b.ResetTimer() 470 for i := 0; i < b.N; i++ { 471 x.Exp(x, b1) 472 } 473 } 474 475 func BenchmarkE2Inverse(b *testing.B) { 476 var a E2 477 _, _ = a.SetRandom() 478 b.ResetTimer() 479 for i := 0; i < b.N; i++ { 480 a.Inverse(&a) 481 } 482 } 483 484 func BenchmarkE2MulNonRes(b *testing.B) { 485 var a E2 486 _, _ = a.SetRandom() 487 b.ResetTimer() 488 for i := 0; i < b.N; i++ { 489 a.MulByNonResidue(&a) 490 } 491 } 492 493 func BenchmarkE2MulNonResInv(b *testing.B) { 494 var a E2 495 _, _ = a.SetRandom() 496 b.ResetTimer() 497 for i := 0; i < b.N; i++ { 498 a.MulByNonResidueInv(&a) 499 } 500 } 501 502 func BenchmarkE2Conjugate(b *testing.B) { 503 var a E2 504 _, _ = a.SetRandom() 505 b.ResetTimer() 506 for i := 0; i < b.N; i++ { 507 a.Conjugate(&a) 508 } 509 } 510 511 func TestE2Div(t *testing.T) { 512 513 parameters := gopter.DefaultTestParameters() 514 properties := gopter.NewProperties(parameters) 515 516 genA := GenE2() 517 genB := GenE2() 518 519 properties.Property("[BLS12-377] dividing then multiplying by the same element does nothing", prop.ForAll( 520 func(a, b *E2) bool { 521 var c E2 522 c.Div(a, b) 523 c.Mul(&c, b) 524 return c.Equal(a) 525 }, 526 genA, 527 genB, 528 )) 529 530 properties.TestingRun(t, gopter.ConsoleReporter(false)) 531 }