github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/hash_to_g2_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  	"github.com/consensys/gnark-crypto/ecc/bn254/fp"
    21  	"github.com/consensys/gnark-crypto/ecc/bn254/internal/fptower"
    22  	"github.com/leanovate/gopter"
    23  	"github.com/leanovate/gopter/prop"
    24  	"math/rand"
    25  	"strings"
    26  	"testing"
    27  )
    28  
    29  func TestHashToFpG2(t *testing.T) {
    30  	for _, c := range encodeToG2Vector.cases {
    31  		elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 2)
    32  		if err != nil {
    33  			t.Error(err)
    34  		}
    35  		g2TestMatchCoord(t, "u", c.msg, c.u, g2CoordAt(elems, 0))
    36  	}
    37  
    38  	for _, c := range hashToG2Vector.cases {
    39  		elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*2)
    40  		if err != nil {
    41  			t.Error(err)
    42  		}
    43  		g2TestMatchCoord(t, "u0", c.msg, c.u0, g2CoordAt(elems, 0))
    44  		g2TestMatchCoord(t, "u1", c.msg, c.u1, g2CoordAt(elems, 1))
    45  	}
    46  }
    47  
    48  func TestMapToCurve2(t *testing.T) {
    49  	t.Parallel()
    50  	parameters := gopter.DefaultTestParameters()
    51  	if testing.Short() {
    52  		parameters.MinSuccessfulTests = nbFuzzShort
    53  	} else {
    54  		parameters.MinSuccessfulTests = nbFuzz
    55  	}
    56  
    57  	properties := gopter.NewProperties(parameters)
    58  
    59  	properties.Property("[G2] mapping output must be on curve", prop.ForAll(
    60  		func(a fptower.E2) bool {
    61  
    62  			g := MapToCurve2(&a)
    63  
    64  			if !g.IsOnCurve() {
    65  				t.Log("SVDW output not on curve")
    66  				return false
    67  			}
    68  
    69  			return true
    70  		},
    71  		GenE2(),
    72  	))
    73  
    74  	properties.TestingRun(t, gopter.ConsoleReporter(false))
    75  
    76  	for _, c := range encodeToG2Vector.cases {
    77  		var u fptower.E2
    78  		g2CoordSetString(&u, c.u)
    79  		q := MapToCurve2(&u)
    80  		g2TestMatchPoint(t, "Q", c.msg, c.Q, &q)
    81  	}
    82  
    83  	for _, c := range hashToG2Vector.cases {
    84  		var u fptower.E2
    85  		g2CoordSetString(&u, c.u0)
    86  		q := MapToCurve2(&u)
    87  		g2TestMatchPoint(t, "Q0", c.msg, c.Q0, &q)
    88  
    89  		g2CoordSetString(&u, c.u1)
    90  		q = MapToCurve2(&u)
    91  		g2TestMatchPoint(t, "Q1", c.msg, c.Q1, &q)
    92  	}
    93  }
    94  
    95  func TestMapToG2(t *testing.T) {
    96  	t.Parallel()
    97  	parameters := gopter.DefaultTestParameters()
    98  	if testing.Short() {
    99  		parameters.MinSuccessfulTests = nbFuzzShort
   100  	} else {
   101  		parameters.MinSuccessfulTests = nbFuzz
   102  	}
   103  
   104  	properties := gopter.NewProperties(parameters)
   105  
   106  	properties.Property("[G2] mapping to curve should output point on the curve", prop.ForAll(
   107  		func(a fptower.E2) bool {
   108  			g := MapToG2(a)
   109  			return g.IsInSubGroup()
   110  		},
   111  		GenE2(),
   112  	))
   113  
   114  	properties.Property("[G2] mapping to curve should be deterministic", prop.ForAll(
   115  		func(a fptower.E2) bool {
   116  			g1 := MapToG2(a)
   117  			g2 := MapToG2(a)
   118  			return g1.Equal(&g2)
   119  		},
   120  		GenE2(),
   121  	))
   122  
   123  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   124  }
   125  
   126  func TestEncodeToG2(t *testing.T) {
   127  	t.Parallel()
   128  	for _, c := range encodeToG2Vector.cases {
   129  		p, err := EncodeToG2([]byte(c.msg), encodeToG2Vector.dst)
   130  		if err != nil {
   131  			t.Fatal(err)
   132  		}
   133  		g2TestMatchPoint(t, "P", c.msg, c.P, &p)
   134  	}
   135  }
   136  
   137  func TestHashToG2(t *testing.T) {
   138  	t.Parallel()
   139  	for _, c := range hashToG2Vector.cases {
   140  		p, err := HashToG2([]byte(c.msg), hashToG2Vector.dst)
   141  		if err != nil {
   142  			t.Fatal(err)
   143  		}
   144  		g2TestMatchPoint(t, "P", c.msg, c.P, &p)
   145  	}
   146  }
   147  
   148  func BenchmarkEncodeToG2(b *testing.B) {
   149  	const size = 54
   150  	bytes := make([]byte, size)
   151  	dst := encodeToG2Vector.dst
   152  	b.ResetTimer()
   153  
   154  	for i := 0; i < b.N; i++ {
   155  
   156  		bytes[rand.Int()%size] = byte(rand.Int()) //#nosec G404 weak rng is fine here
   157  
   158  		if _, err := EncodeToG2(bytes, dst); err != nil {
   159  			b.Fail()
   160  		}
   161  	}
   162  }
   163  
   164  func BenchmarkHashToG2(b *testing.B) {
   165  	const size = 54
   166  	bytes := make([]byte, size)
   167  	dst := hashToG2Vector.dst
   168  	b.ResetTimer()
   169  
   170  	for i := 0; i < b.N; i++ {
   171  
   172  		bytes[rand.Int()%size] = byte(rand.Int()) //#nosec G404 weak rng is fine here
   173  
   174  		if _, err := HashToG2(bytes, dst); err != nil {
   175  			b.Fail()
   176  		}
   177  	}
   178  }
   179  
   180  // Only works on simple extensions (two-story towers)
   181  func g2CoordSetString(z *fptower.E2, s string) {
   182  	ssplit := strings.Split(s, ",")
   183  	if len(ssplit) != 2 {
   184  		panic("not equal to tower size")
   185  	}
   186  	z.SetString(
   187  		ssplit[0],
   188  		ssplit[1],
   189  	)
   190  }
   191  
   192  func g2CoordAt(slice []fp.Element, i int) fptower.E2 {
   193  	return fptower.E2{
   194  		A0: slice[i*2+0],
   195  		A1: slice[i*2+1],
   196  	}
   197  }
   198  
   199  func g2TestMatchCoord(t *testing.T, coordName string, msg string, expectedStr string, seen fptower.E2) {
   200  	var expected fptower.E2
   201  
   202  	g2CoordSetString(&expected, expectedStr)
   203  
   204  	if !expected.Equal(&seen) {
   205  		t.Errorf("mismatch on \"%s\", %s:\n\texpected %s\n\tsaw      %s", msg, coordName, expected.String(), &seen)
   206  	}
   207  }
   208  
   209  func g2TestMatchPoint(t *testing.T, pointName string, msg string, expected point, seen *G2Affine) {
   210  	g2TestMatchCoord(t, pointName+".x", msg, expected.x, seen.X)
   211  	g2TestMatchCoord(t, pointName+".y", msg, expected.y, seen.Y)
   212  }
   213  
   214  var encodeToG2Vector encodeTestVector
   215  var hashToG2Vector hashTestVector