github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-761/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 bw6761 18 19 import ( 20 "github.com/consensys/gnark-crypto/ecc/bw6-761/fp" 21 "github.com/leanovate/gopter" 22 "github.com/leanovate/gopter/prop" 23 "math/rand" 24 "testing" 25 ) 26 27 func TestG2SqrtRatio(t *testing.T) { 28 t.Parallel() 29 parameters := gopter.DefaultTestParameters() 30 if testing.Short() { 31 parameters.MinSuccessfulTests = nbFuzzShort 32 } else { 33 parameters.MinSuccessfulTests = nbFuzz 34 } 35 36 properties := gopter.NewProperties(parameters) 37 38 gen := GenFp() 39 40 properties.Property("G2SqrtRatio must square back to the right value", prop.ForAll( 41 func(u fp.Element, v fp.Element) bool { 42 43 var seen fp.Element 44 qr := g2SqrtRatio(&seen, &u, &v) == 0 45 46 seen. 47 Square(&seen). 48 Mul(&seen, &v) 49 50 var ref fp.Element 51 if qr { 52 ref = u 53 } else { 54 g2MulByZ(&ref, &u) 55 } 56 57 return seen.Equal(&ref) 58 }, gen, gen)) 59 60 properties.TestingRun(t, gopter.ConsoleReporter(false)) 61 } 62 63 func TestHashToFpG2(t *testing.T) { 64 for _, c := range encodeToG2Vector.cases { 65 elems, err := fp.Hash([]byte(c.msg), encodeToG2Vector.dst, 1) 66 if err != nil { 67 t.Error(err) 68 } 69 g2TestMatchCoord(t, "u", c.msg, c.u, g2CoordAt(elems, 0)) 70 } 71 72 for _, c := range hashToG2Vector.cases { 73 elems, err := fp.Hash([]byte(c.msg), hashToG2Vector.dst, 2*1) 74 if err != nil { 75 t.Error(err) 76 } 77 g2TestMatchCoord(t, "u0", c.msg, c.u0, g2CoordAt(elems, 0)) 78 g2TestMatchCoord(t, "u1", c.msg, c.u1, g2CoordAt(elems, 1)) 79 } 80 } 81 82 func TestMapToCurve2(t *testing.T) { 83 t.Parallel() 84 parameters := gopter.DefaultTestParameters() 85 if testing.Short() { 86 parameters.MinSuccessfulTests = nbFuzzShort 87 } else { 88 parameters.MinSuccessfulTests = nbFuzz 89 } 90 91 properties := gopter.NewProperties(parameters) 92 93 properties.Property("[G2] mapping output must be on curve", prop.ForAll( 94 func(a fp.Element) bool { 95 96 g := MapToCurve2(&a) 97 98 if !isOnE2Prime(g) { 99 t.Log("Mapping output not on E' curve") 100 return false 101 } 102 g2Isogeny(&g) 103 104 if !g.IsOnCurve() { 105 t.Log("Isogeny∘SSWU output not on curve") 106 return false 107 } 108 109 return true 110 }, 111 GenFp(), 112 )) 113 114 properties.TestingRun(t, gopter.ConsoleReporter(false)) 115 116 for _, c := range encodeToG2Vector.cases { 117 var u fp.Element 118 g2CoordSetString(&u, c.u) 119 q := MapToCurve2(&u) 120 g2Isogeny(&q) 121 g2TestMatchPoint(t, "Q", c.msg, c.Q, &q) 122 } 123 124 for _, c := range hashToG2Vector.cases { 125 var u fp.Element 126 g2CoordSetString(&u, c.u0) 127 q := MapToCurve2(&u) 128 g2Isogeny(&q) 129 g2TestMatchPoint(t, "Q0", c.msg, c.Q0, &q) 130 131 g2CoordSetString(&u, c.u1) 132 q = MapToCurve2(&u) 133 g2Isogeny(&q) 134 g2TestMatchPoint(t, "Q1", c.msg, c.Q1, &q) 135 } 136 } 137 138 func TestMapToG2(t *testing.T) { 139 t.Parallel() 140 parameters := gopter.DefaultTestParameters() 141 if testing.Short() { 142 parameters.MinSuccessfulTests = nbFuzzShort 143 } else { 144 parameters.MinSuccessfulTests = nbFuzz 145 } 146 147 properties := gopter.NewProperties(parameters) 148 149 properties.Property("[G2] mapping to curve should output point on the curve", prop.ForAll( 150 func(a fp.Element) bool { 151 g := MapToG2(a) 152 return g.IsInSubGroup() 153 }, 154 GenFp(), 155 )) 156 157 properties.Property("[G2] mapping to curve should be deterministic", prop.ForAll( 158 func(a fp.Element) bool { 159 g1 := MapToG2(a) 160 g2 := MapToG2(a) 161 return g1.Equal(&g2) 162 }, 163 GenFp(), 164 )) 165 166 properties.TestingRun(t, gopter.ConsoleReporter(false)) 167 } 168 169 func TestEncodeToG2(t *testing.T) { 170 t.Parallel() 171 for _, c := range encodeToG2Vector.cases { 172 p, err := EncodeToG2([]byte(c.msg), encodeToG2Vector.dst) 173 if err != nil { 174 t.Fatal(err) 175 } 176 g2TestMatchPoint(t, "P", c.msg, c.P, &p) 177 } 178 } 179 180 func TestHashToG2(t *testing.T) { 181 t.Parallel() 182 for _, c := range hashToG2Vector.cases { 183 p, err := HashToG2([]byte(c.msg), hashToG2Vector.dst) 184 if err != nil { 185 t.Fatal(err) 186 } 187 g2TestMatchPoint(t, "P", c.msg, c.P, &p) 188 } 189 } 190 191 func BenchmarkEncodeToG2(b *testing.B) { 192 const size = 54 193 bytes := make([]byte, size) 194 dst := encodeToG2Vector.dst 195 b.ResetTimer() 196 197 for i := 0; i < b.N; i++ { 198 199 bytes[rand.Int()%size] = byte(rand.Int()) //#nosec G404 weak rng is fine here 200 201 if _, err := EncodeToG2(bytes, dst); err != nil { 202 b.Fail() 203 } 204 } 205 } 206 207 func BenchmarkHashToG2(b *testing.B) { 208 const size = 54 209 bytes := make([]byte, size) 210 dst := hashToG2Vector.dst 211 b.ResetTimer() 212 213 for i := 0; i < b.N; i++ { 214 215 bytes[rand.Int()%size] = byte(rand.Int()) //#nosec G404 weak rng is fine here 216 217 if _, err := HashToG2(bytes, dst); err != nil { 218 b.Fail() 219 } 220 } 221 } 222 223 // TODO: Crude. Do something clever in Jacobian 224 func isOnE2Prime(p G2Affine) bool { 225 226 var A, B fp.Element 227 228 A.SetString( 229 "6429719010846137499474887978131198018330761288163789627290055406883908067119696591103101123992665411263189240363728172709848698522760005194862816392151436104205214136976570209818204605171075531070134198773930389453798390056516896", 230 ) 231 232 B.SetString( 233 "5348306863922295212600474030012704926780090705412552782187041272079620891140642329199277344037019889626771397168162938103438296026272884909103171857394985776682488984714989551922989188985164920238405955336107390943902906254560160", 234 ) 235 236 var LHS fp.Element 237 LHS. 238 Square(&p.Y). 239 Sub(&LHS, &B) 240 241 var RHS fp.Element 242 RHS. 243 Square(&p.X). 244 Add(&RHS, &A). 245 Mul(&RHS, &p.X) 246 247 return LHS.Equal(&RHS) 248 } 249 250 // Only works on simple extensions (two-story towers) 251 func g2CoordSetString(z *fp.Element, s string) { 252 z.SetString(s) 253 } 254 255 func g2CoordAt(slice []fp.Element, i int) fp.Element { 256 return slice[i] 257 } 258 259 func g2TestMatchCoord(t *testing.T, coordName string, msg string, expectedStr string, seen fp.Element) { 260 var expected fp.Element 261 262 g2CoordSetString(&expected, expectedStr) 263 264 if !expected.Equal(&seen) { 265 t.Errorf("mismatch on \"%s\", %s:\n\texpected %s\n\tsaw %s", msg, coordName, expected.String(), &seen) 266 } 267 } 268 269 func g2TestMatchPoint(t *testing.T, pointName string, msg string, expected point, seen *G2Affine) { 270 g2TestMatchCoord(t, pointName+".x", msg, expected.x, seen.X) 271 g2TestMatchCoord(t, pointName+".y", msg, expected.y, seen.Y) 272 } 273 274 var encodeToG2Vector encodeTestVector 275 var hashToG2Vector hashTestVector