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