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