github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/marshal_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 bn254 18 19 import ( 20 "bytes" 21 crand "crypto/rand" 22 "io" 23 "math/big" 24 "math/rand/v2" 25 "reflect" 26 "testing" 27 28 "github.com/leanovate/gopter" 29 "github.com/leanovate/gopter/prop" 30 31 "github.com/consensys/gnark-crypto/ecc/bn254/fp" 32 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 33 "github.com/consensys/gnark-crypto/ecc/bn254/internal/fptower" 34 ) 35 36 const ( 37 nbFuzzShort = 10 38 nbFuzz = 100 39 ) 40 41 func TestEncoder(t *testing.T) { 42 t.Parallel() 43 // TODO need proper fuzz testing here 44 45 var inA uint64 46 var inB fr.Element 47 var inC fp.Element 48 var inD G1Affine 49 var inE G1Affine 50 var inF G2Affine 51 var inG []G1Affine 52 var inH []G2Affine 53 var inI []fp.Element 54 var inJ []fr.Element 55 var inK fr.Vector 56 var inL [][]fr.Element 57 var inM [][]uint64 58 59 // set values of inputs 60 inA = rand.Uint64() //#nosec G404 weak rng is fine here 61 inB.SetRandom() 62 inC.SetRandom() 63 inD.ScalarMultiplication(&g1GenAff, new(big.Int).SetUint64(rand.Uint64())) //#nosec G404 weak rng is fine here 64 // inE --> infinity 65 inF.ScalarMultiplication(&g2GenAff, new(big.Int).SetUint64(rand.Uint64())) //#nosec G404 weak rng is fine here 66 inG = make([]G1Affine, 2) 67 inH = make([]G2Affine, 0) 68 inG[1] = inD 69 inI = make([]fp.Element, 3) 70 inI[2] = inD.X 71 inJ = make([]fr.Element, 0) 72 inK = make(fr.Vector, 42) 73 inK[41].SetUint64(42) 74 inL = [][]fr.Element{inJ, inK} 75 inM = [][]uint64{{1, 2}, {4}, {}} 76 77 // encode them, compressed and raw 78 var buf, bufRaw bytes.Buffer 79 enc := NewEncoder(&buf) 80 encRaw := NewEncoder(&bufRaw, RawEncoding()) 81 toEncode := []interface{}{inA, &inB, &inC, &inD, &inE, &inF, inG, inH, inI, inJ, inK, inL, inM} 82 for _, v := range toEncode { 83 if err := enc.Encode(v); err != nil { 84 t.Fatal(err) 85 } 86 if err := encRaw.Encode(v); err != nil { 87 t.Fatal(err) 88 } 89 } 90 91 testDecode := func(t *testing.T, r io.Reader, n int64) { 92 dec := NewDecoder(r) 93 var outA uint64 94 var outB fr.Element 95 var outC fp.Element 96 var outD G1Affine 97 var outE G1Affine 98 outE.X.SetOne() 99 outE.Y.SetUint64(42) 100 var outF G2Affine 101 var outG []G1Affine 102 var outH []G2Affine 103 var outI []fp.Element 104 var outJ []fr.Element 105 var outK fr.Vector 106 var outL [][]fr.Element 107 var outM [][]uint64 108 109 toDecode := []interface{}{&outA, &outB, &outC, &outD, &outE, &outF, &outG, &outH, &outI, &outJ, &outK, &outL, &outM} 110 for _, v := range toDecode { 111 if err := dec.Decode(v); err != nil { 112 t.Fatal(err) 113 } 114 } 115 116 // compare values 117 if inA != outA { 118 t.Fatal("didn't encode/decode uint64 value properly") 119 } 120 121 if !inB.Equal(&outB) || !inC.Equal(&outC) { 122 t.Fatal("decode(encode(Element) failed") 123 } 124 if !inD.Equal(&outD) || !inE.Equal(&outE) { 125 t.Fatal("decode(encode(G1Affine) failed") 126 } 127 if !inF.Equal(&outF) { 128 t.Fatal("decode(encode(G2Affine) failed") 129 } 130 if (len(inG) != len(outG)) || (len(inH) != len(outH)) { 131 t.Fatal("decode(encode(slice(points))) failed") 132 } 133 for i := 0; i < len(inG); i++ { 134 if !inG[i].Equal(&outG[i]) { 135 t.Fatal("decode(encode(slice(points))) failed") 136 } 137 } 138 if (len(inI) != len(outI)) || (len(inJ) != len(outJ)) { 139 t.Fatal("decode(encode(slice(elements))) failed") 140 } 141 for i := 0; i < len(inI); i++ { 142 if !inI[i].Equal(&outI[i]) { 143 t.Fatal("decode(encode(slice(elements))) failed") 144 } 145 } 146 if !reflect.DeepEqual(inK, outK) { 147 t.Fatal("decode(encode(vector)) failed") 148 } 149 if !reflect.DeepEqual(inL, outL) { 150 t.Fatal("decode(encode(sliceĀ²(elements))) failed") 151 } 152 if !reflect.DeepEqual(inM, outM) { 153 t.Fatal("decode(encode(sliceĀ²(uint64))) failed") 154 } 155 if n != dec.BytesRead() { 156 t.Fatal("bytes read don't match bytes written") 157 } 158 } 159 160 // decode them 161 testDecode(t, &buf, enc.BytesWritten()) 162 testDecode(t, &bufRaw, encRaw.BytesWritten()) 163 164 } 165 166 func TestIsCompressed(t *testing.T) { 167 t.Parallel() 168 var g1Inf, g1 G1Affine 169 var g2Inf, g2 G2Affine 170 171 g1 = g1GenAff 172 g2 = g2GenAff 173 174 { 175 b := g1Inf.Bytes() 176 if !isCompressed(b[0]) { 177 t.Fatal("g1Inf.Bytes() should be compressed") 178 } 179 } 180 181 { 182 b := g1Inf.RawBytes() 183 if isCompressed(b[0]) { 184 t.Fatal("g1Inf.RawBytes() should be uncompressed") 185 } 186 } 187 188 { 189 b := g1.Bytes() 190 if !isCompressed(b[0]) { 191 t.Fatal("g1.Bytes() should be compressed") 192 } 193 } 194 195 { 196 b := g1.RawBytes() 197 if isCompressed(b[0]) { 198 t.Fatal("g1.RawBytes() should be uncompressed") 199 } 200 } 201 202 { 203 b := g2Inf.Bytes() 204 if !isCompressed(b[0]) { 205 t.Fatal("g2Inf.Bytes() should be compressed") 206 } 207 } 208 209 { 210 b := g2Inf.RawBytes() 211 if isCompressed(b[0]) { 212 t.Fatal("g2Inf.RawBytes() should be uncompressed") 213 } 214 } 215 216 { 217 b := g2.Bytes() 218 if !isCompressed(b[0]) { 219 t.Fatal("g2.Bytes() should be compressed") 220 } 221 } 222 223 { 224 b := g2.RawBytes() 225 if isCompressed(b[0]) { 226 t.Fatal("g2.RawBytes() should be uncompressed") 227 } 228 } 229 230 } 231 232 func TestG1AffineSerialization(t *testing.T) { 233 t.Parallel() 234 // test round trip serialization of infinity 235 { 236 // compressed 237 { 238 var p1, p2 G1Affine 239 p2.X.SetRandom() 240 p2.Y.SetRandom() 241 buf := p1.Bytes() 242 n, err := p2.SetBytes(buf[:]) 243 if err != nil { 244 t.Fatal(err) 245 } 246 if n != SizeOfG1AffineCompressed { 247 t.Fatal("invalid number of bytes consumed in buffer") 248 } 249 if !(p2.X.IsZero() && p2.Y.IsZero()) { 250 t.Fatal("deserialization of uncompressed infinity point is not infinity") 251 } 252 } 253 254 // uncompressed 255 { 256 var p1, p2 G1Affine 257 p2.X.SetRandom() 258 p2.Y.SetRandom() 259 buf := p1.RawBytes() 260 n, err := p2.SetBytes(buf[:]) 261 if err != nil { 262 t.Fatal(err) 263 } 264 if n != SizeOfG1AffineUncompressed { 265 t.Fatal("invalid number of bytes consumed in buffer") 266 } 267 if !(p2.X.IsZero() && p2.Y.IsZero()) { 268 t.Fatal("deserialization of uncompressed infinity point is not infinity") 269 } 270 } 271 } 272 273 parameters := gopter.DefaultTestParameters() 274 if testing.Short() { 275 parameters.MinSuccessfulTests = nbFuzzShort 276 } else { 277 parameters.MinSuccessfulTests = nbFuzz 278 } 279 280 properties := gopter.NewProperties(parameters) 281 282 properties.Property("[G1] Affine SetBytes(RawBytes) should stay the same", prop.ForAll( 283 func(a fp.Element) bool { 284 var start, end G1Affine 285 var ab big.Int 286 a.BigInt(&ab) 287 start.ScalarMultiplication(&g1GenAff, &ab) 288 289 buf := start.RawBytes() 290 n, err := end.SetBytes(buf[:]) 291 if err != nil { 292 return false 293 } 294 if n != SizeOfG1AffineUncompressed { 295 return false 296 } 297 return start.X.Equal(&end.X) && start.Y.Equal(&end.Y) 298 }, 299 GenFp(), 300 )) 301 302 properties.Property("[G1] Affine SetBytes(Bytes()) should stay the same", prop.ForAll( 303 func(a fp.Element) bool { 304 var start, end G1Affine 305 var ab big.Int 306 a.BigInt(&ab) 307 start.ScalarMultiplication(&g1GenAff, &ab) 308 309 buf := start.Bytes() 310 n, err := end.SetBytes(buf[:]) 311 if err != nil { 312 return false 313 } 314 if n != SizeOfG1AffineCompressed { 315 return false 316 } 317 return start.X.Equal(&end.X) && start.Y.Equal(&end.Y) 318 }, 319 GenFp(), 320 )) 321 322 properties.TestingRun(t, gopter.ConsoleReporter(false)) 323 } 324 325 func TestG2AffineSerialization(t *testing.T) { 326 t.Parallel() 327 // test round trip serialization of infinity 328 { 329 // compressed 330 { 331 var p1, p2 G2Affine 332 p2.X.SetRandom() 333 p2.Y.SetRandom() 334 buf := p1.Bytes() 335 n, err := p2.SetBytes(buf[:]) 336 if err != nil { 337 t.Fatal(err) 338 } 339 if n != SizeOfG2AffineCompressed { 340 t.Fatal("invalid number of bytes consumed in buffer") 341 } 342 if !(p2.X.IsZero() && p2.Y.IsZero()) { 343 t.Fatal("deserialization of uncompressed infinity point is not infinity") 344 } 345 } 346 347 // uncompressed 348 { 349 var p1, p2 G2Affine 350 p2.X.SetRandom() 351 p2.Y.SetRandom() 352 buf := p1.RawBytes() 353 n, err := p2.SetBytes(buf[:]) 354 if err != nil { 355 t.Fatal(err) 356 } 357 if n != SizeOfG2AffineUncompressed { 358 t.Fatal("invalid number of bytes consumed in buffer") 359 } 360 if !(p2.X.IsZero() && p2.Y.IsZero()) { 361 t.Fatal("deserialization of uncompressed infinity point is not infinity") 362 } 363 } 364 } 365 366 parameters := gopter.DefaultTestParameters() 367 if testing.Short() { 368 parameters.MinSuccessfulTests = nbFuzzShort 369 } else { 370 parameters.MinSuccessfulTests = nbFuzz 371 } 372 373 properties := gopter.NewProperties(parameters) 374 375 properties.Property("[G2] Affine SetBytes(RawBytes) should stay the same", prop.ForAll( 376 func(a fp.Element) bool { 377 var start, end G2Affine 378 var ab big.Int 379 a.BigInt(&ab) 380 start.ScalarMultiplication(&g2GenAff, &ab) 381 382 buf := start.RawBytes() 383 n, err := end.SetBytes(buf[:]) 384 if err != nil { 385 return false 386 } 387 if n != SizeOfG2AffineUncompressed { 388 return false 389 } 390 return start.X.Equal(&end.X) && start.Y.Equal(&end.Y) 391 }, 392 GenFp(), 393 )) 394 395 properties.Property("[G2] Affine SetBytes(Bytes()) should stay the same", prop.ForAll( 396 func(a fp.Element) bool { 397 var start, end G2Affine 398 var ab big.Int 399 a.BigInt(&ab) 400 start.ScalarMultiplication(&g2GenAff, &ab) 401 402 buf := start.Bytes() 403 n, err := end.SetBytes(buf[:]) 404 if err != nil { 405 return false 406 } 407 if n != SizeOfG2AffineCompressed { 408 return false 409 } 410 return start.X.Equal(&end.X) && start.Y.Equal(&end.Y) 411 }, 412 GenFp(), 413 )) 414 415 properties.TestingRun(t, gopter.ConsoleReporter(false)) 416 } 417 418 // define Gopters generators 419 420 // GenFr generates an Fr element 421 func GenFr() gopter.Gen { 422 return func(genParams *gopter.GenParameters) *gopter.GenResult { 423 var elmt fr.Element 424 425 if _, err := elmt.SetRandom(); err != nil { 426 panic(err) 427 } 428 429 return gopter.NewGenResult(elmt, gopter.NoShrinker) 430 } 431 } 432 433 // GenFp generates an Fp element 434 func GenFp() gopter.Gen { 435 return func(genParams *gopter.GenParameters) *gopter.GenResult { 436 var elmt fp.Element 437 438 if _, err := elmt.SetRandom(); err != nil { 439 panic(err) 440 } 441 442 return gopter.NewGenResult(elmt, gopter.NoShrinker) 443 } 444 } 445 446 // GenE2 generates an fptower.E2 elmt 447 func GenE2() gopter.Gen { 448 return gopter.CombineGens( 449 GenFp(), 450 GenFp(), 451 ).Map(func(values []interface{}) fptower.E2 { 452 return fptower.E2{A0: values[0].(fp.Element), A1: values[1].(fp.Element)} 453 }) 454 } 455 456 // GenE6 generates an fptower.E6 elmt 457 func GenE6() gopter.Gen { 458 return gopter.CombineGens( 459 GenE2(), 460 GenE2(), 461 GenE2(), 462 ).Map(func(values []interface{}) fptower.E6 { 463 return fptower.E6{B0: values[0].(fptower.E2), B1: values[1].(fptower.E2), B2: values[2].(fptower.E2)} 464 }) 465 } 466 467 // GenE12 generates an fptower.E6 elmt 468 func GenE12() gopter.Gen { 469 return gopter.CombineGens( 470 GenE6(), 471 GenE6(), 472 ).Map(func(values []interface{}) fptower.E12 { 473 return fptower.E12{C0: values[0].(fptower.E6), C1: values[1].(fptower.E6)} 474 }) 475 } 476 477 // GenBigInt generates a big.Int 478 func GenBigInt() gopter.Gen { 479 return func(genParams *gopter.GenParameters) *gopter.GenResult { 480 var s big.Int 481 var b [fp.Bytes]byte 482 _, err := crand.Read(b[:]) 483 if err != nil { 484 panic(err) 485 } 486 s.SetBytes(b[:]) 487 genResult := gopter.NewGenResult(s, gopter.NoShrinker) 488 return genResult 489 } 490 }