github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/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 bls12378
    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/bls12-378/fp"
    32  	"github.com/consensys/gnark-crypto/ecc/bls12-378/fr"
    33  	"github.com/consensys/gnark-crypto/ecc/bls12-378/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 TestG1AffineInvalidBitMask(t *testing.T) {
   233  	t.Parallel()
   234  	var buf [SizeOfG1AffineCompressed]byte
   235  	crand.Read(buf[:])
   236  
   237  	var p G1Affine
   238  	buf[0] = 0b111 << 5
   239  	if _, err := p.SetBytes(buf[:]); err != ErrInvalidEncoding {
   240  		t.Fatal("should error on invalid bit mask")
   241  	}
   242  	buf[0] = 0b011 << 5
   243  	if _, err := p.SetBytes(buf[:]); err != ErrInvalidEncoding {
   244  		t.Fatal("should error on invalid bit mask")
   245  	}
   246  	buf[0] = 0b001 << 5
   247  	if _, err := p.SetBytes(buf[:]); err != ErrInvalidEncoding {
   248  		t.Fatal("should error on invalid bit mask")
   249  	}
   250  }
   251  
   252  func TestG1AffineSerialization(t *testing.T) {
   253  	t.Parallel()
   254  	// test round trip serialization of infinity
   255  	{
   256  		// compressed
   257  		{
   258  			var p1, p2 G1Affine
   259  			p2.X.SetRandom()
   260  			p2.Y.SetRandom()
   261  			buf := p1.Bytes()
   262  			n, err := p2.SetBytes(buf[:])
   263  			if err != nil {
   264  				t.Fatal(err)
   265  			}
   266  			if n != SizeOfG1AffineCompressed {
   267  				t.Fatal("invalid number of bytes consumed in buffer")
   268  			}
   269  			if !(p2.X.IsZero() && p2.Y.IsZero()) {
   270  				t.Fatal("deserialization of uncompressed infinity point is not infinity")
   271  			}
   272  		}
   273  
   274  		// uncompressed
   275  		{
   276  			var p1, p2 G1Affine
   277  			p2.X.SetRandom()
   278  			p2.Y.SetRandom()
   279  			buf := p1.RawBytes()
   280  			n, err := p2.SetBytes(buf[:])
   281  			if err != nil {
   282  				t.Fatal(err)
   283  			}
   284  			if n != SizeOfG1AffineUncompressed {
   285  				t.Fatal("invalid number of bytes consumed in buffer")
   286  			}
   287  			if !(p2.X.IsZero() && p2.Y.IsZero()) {
   288  				t.Fatal("deserialization of uncompressed infinity point is not infinity")
   289  			}
   290  		}
   291  	}
   292  
   293  	parameters := gopter.DefaultTestParameters()
   294  	if testing.Short() {
   295  		parameters.MinSuccessfulTests = nbFuzzShort
   296  	} else {
   297  		parameters.MinSuccessfulTests = nbFuzz
   298  	}
   299  
   300  	properties := gopter.NewProperties(parameters)
   301  
   302  	properties.Property("[G1] Affine SetBytes(RawBytes) 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.RawBytes()
   310  			n, err := end.SetBytes(buf[:])
   311  			if err != nil {
   312  				return false
   313  			}
   314  			if n != SizeOfG1AffineUncompressed {
   315  				return false
   316  			}
   317  			return start.X.Equal(&end.X) && start.Y.Equal(&end.Y)
   318  		},
   319  		GenFp(),
   320  	))
   321  
   322  	properties.Property("[G1] Affine SetBytes(Bytes()) should stay the same", prop.ForAll(
   323  		func(a fp.Element) bool {
   324  			var start, end G1Affine
   325  			var ab big.Int
   326  			a.BigInt(&ab)
   327  			start.ScalarMultiplication(&g1GenAff, &ab)
   328  
   329  			buf := start.Bytes()
   330  			n, err := end.SetBytes(buf[:])
   331  			if err != nil {
   332  				return false
   333  			}
   334  			if n != SizeOfG1AffineCompressed {
   335  				return false
   336  			}
   337  			return start.X.Equal(&end.X) && start.Y.Equal(&end.Y)
   338  		},
   339  		GenFp(),
   340  	))
   341  
   342  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   343  }
   344  
   345  func TestG2AffineInvalidBitMask(t *testing.T) {
   346  	t.Parallel()
   347  	var buf [SizeOfG2AffineCompressed]byte
   348  	crand.Read(buf[:])
   349  
   350  	var p G2Affine
   351  	buf[0] = 0b111 << 5
   352  	if _, err := p.SetBytes(buf[:]); err != ErrInvalidEncoding {
   353  		t.Fatal("should error on invalid bit mask")
   354  	}
   355  	buf[0] = 0b011 << 5
   356  	if _, err := p.SetBytes(buf[:]); err != ErrInvalidEncoding {
   357  		t.Fatal("should error on invalid bit mask")
   358  	}
   359  	buf[0] = 0b001 << 5
   360  	if _, err := p.SetBytes(buf[:]); err != ErrInvalidEncoding {
   361  		t.Fatal("should error on invalid bit mask")
   362  	}
   363  }
   364  
   365  func TestG2AffineSerialization(t *testing.T) {
   366  	t.Parallel()
   367  	// test round trip serialization of infinity
   368  	{
   369  		// compressed
   370  		{
   371  			var p1, p2 G2Affine
   372  			p2.X.SetRandom()
   373  			p2.Y.SetRandom()
   374  			buf := p1.Bytes()
   375  			n, err := p2.SetBytes(buf[:])
   376  			if err != nil {
   377  				t.Fatal(err)
   378  			}
   379  			if n != SizeOfG2AffineCompressed {
   380  				t.Fatal("invalid number of bytes consumed in buffer")
   381  			}
   382  			if !(p2.X.IsZero() && p2.Y.IsZero()) {
   383  				t.Fatal("deserialization of uncompressed infinity point is not infinity")
   384  			}
   385  		}
   386  
   387  		// uncompressed
   388  		{
   389  			var p1, p2 G2Affine
   390  			p2.X.SetRandom()
   391  			p2.Y.SetRandom()
   392  			buf := p1.RawBytes()
   393  			n, err := p2.SetBytes(buf[:])
   394  			if err != nil {
   395  				t.Fatal(err)
   396  			}
   397  			if n != SizeOfG2AffineUncompressed {
   398  				t.Fatal("invalid number of bytes consumed in buffer")
   399  			}
   400  			if !(p2.X.IsZero() && p2.Y.IsZero()) {
   401  				t.Fatal("deserialization of uncompressed infinity point is not infinity")
   402  			}
   403  		}
   404  	}
   405  
   406  	parameters := gopter.DefaultTestParameters()
   407  	if testing.Short() {
   408  		parameters.MinSuccessfulTests = nbFuzzShort
   409  	} else {
   410  		parameters.MinSuccessfulTests = nbFuzz
   411  	}
   412  
   413  	properties := gopter.NewProperties(parameters)
   414  
   415  	properties.Property("[G2] Affine SetBytes(RawBytes) should stay the same", prop.ForAll(
   416  		func(a fp.Element) bool {
   417  			var start, end G2Affine
   418  			var ab big.Int
   419  			a.BigInt(&ab)
   420  			start.ScalarMultiplication(&g2GenAff, &ab)
   421  
   422  			buf := start.RawBytes()
   423  			n, err := end.SetBytes(buf[:])
   424  			if err != nil {
   425  				return false
   426  			}
   427  			if n != SizeOfG2AffineUncompressed {
   428  				return false
   429  			}
   430  			return start.X.Equal(&end.X) && start.Y.Equal(&end.Y)
   431  		},
   432  		GenFp(),
   433  	))
   434  
   435  	properties.Property("[G2] Affine SetBytes(Bytes()) should stay the same", prop.ForAll(
   436  		func(a fp.Element) bool {
   437  			var start, end G2Affine
   438  			var ab big.Int
   439  			a.BigInt(&ab)
   440  			start.ScalarMultiplication(&g2GenAff, &ab)
   441  
   442  			buf := start.Bytes()
   443  			n, err := end.SetBytes(buf[:])
   444  			if err != nil {
   445  				return false
   446  			}
   447  			if n != SizeOfG2AffineCompressed {
   448  				return false
   449  			}
   450  			return start.X.Equal(&end.X) && start.Y.Equal(&end.Y)
   451  		},
   452  		GenFp(),
   453  	))
   454  
   455  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   456  }
   457  
   458  // define Gopters generators
   459  
   460  // GenFr generates an Fr element
   461  func GenFr() gopter.Gen {
   462  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
   463  		var elmt fr.Element
   464  
   465  		if _, err := elmt.SetRandom(); err != nil {
   466  			panic(err)
   467  		}
   468  
   469  		return gopter.NewGenResult(elmt, gopter.NoShrinker)
   470  	}
   471  }
   472  
   473  // GenFp generates an Fp element
   474  func GenFp() gopter.Gen {
   475  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
   476  		var elmt fp.Element
   477  
   478  		if _, err := elmt.SetRandom(); err != nil {
   479  			panic(err)
   480  		}
   481  
   482  		return gopter.NewGenResult(elmt, gopter.NoShrinker)
   483  	}
   484  }
   485  
   486  // GenE2 generates an fptower.E2 elmt
   487  func GenE2() gopter.Gen {
   488  	return gopter.CombineGens(
   489  		GenFp(),
   490  		GenFp(),
   491  	).Map(func(values []interface{}) fptower.E2 {
   492  		return fptower.E2{A0: values[0].(fp.Element), A1: values[1].(fp.Element)}
   493  	})
   494  }
   495  
   496  // GenE6 generates an fptower.E6 elmt
   497  func GenE6() gopter.Gen {
   498  	return gopter.CombineGens(
   499  		GenE2(),
   500  		GenE2(),
   501  		GenE2(),
   502  	).Map(func(values []interface{}) fptower.E6 {
   503  		return fptower.E6{B0: values[0].(fptower.E2), B1: values[1].(fptower.E2), B2: values[2].(fptower.E2)}
   504  	})
   505  }
   506  
   507  // GenE12 generates an fptower.E6 elmt
   508  func GenE12() gopter.Gen {
   509  	return gopter.CombineGens(
   510  		GenE6(),
   511  		GenE6(),
   512  	).Map(func(values []interface{}) fptower.E12 {
   513  		return fptower.E12{C0: values[0].(fptower.E6), C1: values[1].(fptower.E6)}
   514  	})
   515  }
   516  
   517  // GenBigInt generates a big.Int
   518  func GenBigInt() gopter.Gen {
   519  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
   520  		var s big.Int
   521  		var b [fp.Bytes]byte
   522  		_, err := crand.Read(b[:])
   523  		if err != nil {
   524  			panic(err)
   525  		}
   526  		s.SetBytes(b[:])
   527  		genResult := gopter.NewGenResult(s, gopter.NoShrinker)
   528  		return genResult
   529  	}
   530  }