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  }