github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-315/internal/fptower/e4_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 package fptower 16 17 import ( 18 "testing" 19 20 "github.com/consensys/gnark-crypto/ecc/bls24-315/fp" 21 "github.com/leanovate/gopter" 22 "github.com/leanovate/gopter/prop" 23 ) 24 25 // ------------------------------------------------------------ 26 // tests 27 28 func TestE4ReceiverIsOperand(t *testing.T) { 29 t.Parallel() 30 31 parameters := gopter.DefaultTestParameters() 32 parameters.MinSuccessfulTests = 100 33 34 properties := gopter.NewProperties(parameters) 35 36 genA := GenE4() 37 genB := GenE4() 38 39 properties.Property("[BLS24-315] Having the receiver as operand (addition) should output the same result", prop.ForAll( 40 func(a, b *E4) bool { 41 var c, d E4 42 d.Set(a) 43 c.Add(a, b) 44 a.Add(a, b) 45 b.Add(&d, b) 46 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 47 }, 48 genA, 49 genB, 50 )) 51 52 properties.Property("[BLS24-315] Having the receiver as operand (sub) should output the same result", prop.ForAll( 53 func(a, b *E4) bool { 54 var c, d E4 55 d.Set(a) 56 c.Sub(a, b) 57 a.Sub(a, b) 58 b.Sub(&d, b) 59 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 60 }, 61 genA, 62 genB, 63 )) 64 65 properties.Property("[BLS24-315] Having the receiver as operand (mul) should output the same result", prop.ForAll( 66 func(a, b *E4) bool { 67 var c, d E4 68 d.Set(a) 69 c.Mul(a, b) 70 a.Mul(a, b) 71 b.Mul(&d, b) 72 return a.Equal(b) && a.Equal(&c) && b.Equal(&c) 73 }, 74 genA, 75 genB, 76 )) 77 78 properties.Property("[BLS24-315] Having the receiver as operand (square) should output the same result", prop.ForAll( 79 func(a *E4) bool { 80 var b E4 81 b.Square(a) 82 a.Square(a) 83 return a.Equal(&b) 84 }, 85 genA, 86 )) 87 88 properties.Property("[BLS24-315] Having the receiver as operand (double) should output the same result", prop.ForAll( 89 func(a *E4) bool { 90 var b E4 91 b.Double(a) 92 a.Double(a) 93 return a.Equal(&b) 94 }, 95 genA, 96 )) 97 98 properties.Property("[BLS24-315] Having the receiver as operand (mul by non residue) should output the same result", prop.ForAll( 99 func(a *E4) bool { 100 var b E4 101 b.MulByNonResidue(a) 102 a.MulByNonResidue(a) 103 return a.Equal(&b) 104 }, 105 genA, 106 )) 107 108 properties.Property("[BLS24-315] Having the receiver as operand (mul by non residue inverse) should output the same result", prop.ForAll( 109 func(a *E4) bool { 110 var b E4 111 b.MulByNonResidueInv(a) 112 a.MulByNonResidueInv(a) 113 return a.Equal(&b) 114 }, 115 genA, 116 )) 117 118 properties.Property("[BLS24-315] Having the receiver as operand (Inverse) should output the same result", prop.ForAll( 119 func(a *E4) bool { 120 var b E4 121 b.Inverse(a) 122 a.Inverse(a) 123 return a.Equal(&b) 124 }, 125 genA, 126 )) 127 128 properties.Property("[BLS24-315] Having the receiver as operand (Conjugate) should output the same result", prop.ForAll( 129 func(a *E4) bool { 130 var b E4 131 b.Conjugate(a) 132 a.Conjugate(a) 133 return a.Equal(&b) 134 }, 135 genA, 136 )) 137 138 properties.Property("[BLS24-315] Having the receiver as operand (Sqrt) should output the same result", prop.ForAll( 139 func(a *E4) bool { 140 var b, c, d, s E4 141 142 s.Square(a) 143 a.Set(&s) 144 b.Set(&s) 145 146 a.Sqrt(a) 147 b.Sqrt(&b) 148 149 c.Square(a) 150 d.Square(&b) 151 return c.Equal(&d) 152 }, 153 genA, 154 )) 155 156 properties.TestingRun(t, gopter.ConsoleReporter(false)) 157 } 158 159 func TestE4Ops(t *testing.T) { 160 t.Parallel() 161 162 parameters := gopter.DefaultTestParameters() 163 parameters.MinSuccessfulTests = 100 164 165 properties := gopter.NewProperties(parameters) 166 167 genA := GenE4() 168 genB := GenE4() 169 170 properties.Property("[BLS24-315] sub & add should leave an element invariant", prop.ForAll( 171 func(a, b *E4) bool { 172 var c E4 173 c.Set(a) 174 c.Add(&c, b).Sub(&c, b) 175 return c.Equal(a) 176 }, 177 genA, 178 genB, 179 )) 180 181 properties.Property("[BLS24-315] mul & inverse should leave an element invariant", prop.ForAll( 182 func(a, b *E4) bool { 183 var c, d E4 184 d.Inverse(b) 185 c.Set(a) 186 c.Mul(&c, b).Mul(&c, &d) 187 return c.Equal(a) 188 }, 189 genA, 190 genB, 191 )) 192 193 properties.Property("[BLS24-315] BatchInvertE4 should output the same result as Inverse", prop.ForAll( 194 func(a, b, c *E4) bool { 195 196 batch := BatchInvertE4([]E4{*a, *b, *c}) 197 a.Inverse(a) 198 b.Inverse(b) 199 c.Inverse(c) 200 return a.Equal(&batch[0]) && b.Equal(&batch[1]) && c.Equal(&batch[2]) 201 }, 202 genA, 203 genA, 204 genB, 205 )) 206 207 properties.Property("[BLS24-315] inverse twice should leave an element invariant", prop.ForAll( 208 func(a *E4) bool { 209 var b E4 210 b.Inverse(a).Inverse(&b) 211 return a.Equal(&b) 212 }, 213 genA, 214 )) 215 216 properties.Property("[BLS24-315] square and mul should output the same result", prop.ForAll( 217 func(a *E4) bool { 218 var b, c E4 219 b.Mul(a, a) 220 c.Square(a) 221 return b.Equal(&c) 222 }, 223 genA, 224 )) 225 226 properties.Property("[BLS24-315] Legendre on square should output 1", prop.ForAll( 227 func(a *E4) bool { 228 var b E4 229 b.Square(a) 230 c := b.Legendre() 231 return c == 1 232 }, 233 genA, 234 )) 235 236 properties.Property("[BLS24-315] square(sqrt) should leave an element invariant", prop.ForAll( 237 func(a *E4) bool { 238 var b, c, d, e E4 239 b.Square(a) 240 c.Sqrt(&b) 241 d.Square(&c) 242 e.Neg(a) 243 return (c.Equal(a) || c.Equal(&e)) && d.Equal(&b) 244 }, 245 genA, 246 )) 247 248 properties.Property("[BLS24-315] Mulbynonres mulbynonresinv should leave the element invariant", prop.ForAll( 249 func(a *E4) bool { 250 var b E4 251 b.MulByNonResidue(a).MulByNonResidueInv(&b) 252 return a.Equal(&b) 253 }, 254 genA, 255 )) 256 257 properties.Property("[BLS24-315] Frobenius of x in E4 should be equal to x^q", prop.ForAll( 258 func(a *E4) bool { 259 var b, c E4 260 q := fp.Modulus() 261 b.Frobenius(a) 262 c.Exp(*a, q) 263 return c.Equal(&b) 264 }, 265 genA, 266 )) 267 268 properties.TestingRun(t, gopter.ConsoleReporter(false)) 269 } 270 271 // ------------------------------------------------------------ 272 // benches 273 274 func BenchmarkE4Add(b *testing.B) { 275 var a, c E4 276 _, _ = a.SetRandom() 277 _, _ = c.SetRandom() 278 b.ResetTimer() 279 for i := 0; i < b.N; i++ { 280 a.Add(&a, &c) 281 } 282 } 283 284 func BenchmarkE4Sub(b *testing.B) { 285 var a, c E4 286 _, _ = a.SetRandom() 287 _, _ = c.SetRandom() 288 b.ResetTimer() 289 for i := 0; i < b.N; i++ { 290 a.Sub(&a, &c) 291 } 292 } 293 294 func BenchmarkE4Mul(b *testing.B) { 295 var a, c E4 296 _, _ = a.SetRandom() 297 _, _ = c.SetRandom() 298 b.ResetTimer() 299 for i := 0; i < b.N; i++ { 300 a.Mul(&a, &c) 301 } 302 } 303 304 func BenchmarkE4Square(b *testing.B) { 305 var a E4 306 _, _ = a.SetRandom() 307 b.ResetTimer() 308 for i := 0; i < b.N; i++ { 309 a.Square(&a) 310 } 311 } 312 313 func BenchmarkE4Sqrt(b *testing.B) { 314 var a E4 315 _, _ = a.SetRandom() 316 b.ResetTimer() 317 for i := 0; i < b.N; i++ { 318 a.Sqrt(&a) 319 } 320 } 321 322 func BenchmarkE4Inverse(b *testing.B) { 323 var a E4 324 _, _ = a.SetRandom() 325 b.ResetTimer() 326 for i := 0; i < b.N; i++ { 327 a.Inverse(&a) 328 } 329 } 330 331 func BenchmarkE4MulNonRes(b *testing.B) { 332 var a E4 333 _, _ = a.SetRandom() 334 b.ResetTimer() 335 for i := 0; i < b.N; i++ { 336 a.MulByNonResidue(&a) 337 } 338 } 339 340 func BenchmarkE4MulNonResInv(b *testing.B) { 341 var a E4 342 _, _ = a.SetRandom() 343 b.ResetTimer() 344 for i := 0; i < b.N; i++ { 345 a.MulByNonResidueInv(&a) 346 } 347 } 348 func BenchmarkE4Conjugate(b *testing.B) { 349 var a E4 350 _, _ = a.SetRandom() 351 b.ResetTimer() 352 for i := 0; i < b.N; i++ { 353 a.Conjugate(&a) 354 } 355 }