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