github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-315/hash_to_g2.go (about) 1 // Copyright 2020 ConsenSys AG 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 package bls24315 16 17 import ( 18 "github.com/consensys/gnark-crypto/ecc/bls24-315/fp" 19 "github.com/consensys/gnark-crypto/ecc/bls24-315/internal/fptower" 20 ) 21 22 // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-4.1 23 // Shallue and van de Woestijne method, works for any elliptic curve in Weierstrass curve 24 func MapToCurve2(u fptower.E4) G2Affine { 25 26 var res G2Affine 27 28 // constants 29 // sage script to find z: https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#appendix-E.1 30 var z, c1, c2, c3, c4 fptower.E4 31 z.B0.A0.SetOne() 32 z.B0.A1.SetString("0") 33 z.B1.A0.SetOne() 34 z.B1.A1.SetString("0") 35 c1.B0.A0.SetOne() 36 c1.B0.A1.SetOne() 37 c1.B1.A0.SetString("2") 38 c1.B1.A1.SetString("6108483493771298205388567675447533806912846525679192205394505462405828322019437284165171866703") 39 c2.B0.A0.SetString("19852571354756719167512844945204484872466751208457374667532142752818942046563171173536808566784") 40 c2.B0.A1.SetString("0") 41 c2.B1.A0.SetString("19852571354756719167512844945204484872466751208457374667532142752818942046563171173536808566784") 42 c2.B1.A1.SetString("0") 43 44 c3.B0.A0.SetString("14181901575451930365156064137229663961789100070994427419777314377609453770227083005360995137239") 45 c3.B0.A1.SetString("38867788984497805540592493226397363174027239449768861944710564870925669104016488974244557160817") 46 c3.B1.A0.SetString("7207770078990411004130237352587865513334954456592365258287987262730492706089979112564450405406") 47 c3.B1.A1.SetString("11314632945591044023254019576500732396578160594635551958097682961894415495755352199773541527735") 48 49 var tv1, tv2, tv3, tv4, one, x1, gx1, x2, gx2, x3, x, gx, y fptower.E4 50 one.SetOne() 51 tv1.Square(&u).Mul(&tv1, &c1) 52 tv2.Add(&one, &tv1) 53 tv1.Sub(&one, &tv1) 54 tv3.Mul(&tv2, &tv1).Inverse(&tv3) 55 tv4.Mul(&u, &tv1) 56 tv4.Mul(&tv4, &tv3) 57 tv4.Mul(&tv4, &c3) 58 x1.Sub(&c2, &tv4) 59 gx1.Square(&x1) 60 // 12. gx1 = gx1 + A 61 gx1.Mul(&gx1, &x1) 62 gx1.Add(&gx1, &bTwistCurveCoeff) 63 e1 := gx1.Legendre() 64 x2.Add(&c2, &tv4) 65 gx2.Square(&x2) 66 // 18. gx2 = gx2 + A 67 gx2.Mul(&gx2, &x2) 68 gx2.Add(&gx2, &bTwistCurveCoeff) 69 e2 := gx2.Legendre() - e1 // 2 if is_square(gx2) AND NOT e1 70 x3.Square(&tv2) 71 x3.Mul(&x3, &tv3) 72 x3.Square(&x3) 73 x3.Mul(&x3, &c4) 74 x3.Add(&x3, &z) 75 if e1 == 1 { 76 x.Set(&x1) 77 } else { 78 x.Set(&x3) 79 } 80 if e2 == 2 { 81 x.Set(&x2) 82 } 83 gx.Square(&x) 84 // gx = gx + A 85 gx.Mul(&gx, &x) 86 gx.Add(&gx, &bTwistCurveCoeff) 87 y.Sqrt(&gx) 88 e3 := sign0(u.B0.A0) && sign0(y.B0.A0) 89 if !e3 { 90 y.Neg(&y) 91 } 92 res.X.Set(&x) 93 res.Y.Set(&y) 94 95 return res 96 } 97 98 // MapToG2 maps an fp.Element to a point on the curve using the Shallue and van de Woestijne map 99 // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-2.2.1 100 func MapToG2(t fptower.E4) G2Affine { 101 res := MapToCurve2(t) 102 res.ClearCofactor(&res) 103 return res 104 } 105 106 // EncodeToG2 maps an fp.Element to a point on the curve using the Shallue and van de Woestijne map 107 // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-2.2.2 108 func EncodeToG2(msg, dst []byte) (G2Affine, error) { 109 var res G2Affine 110 _t, err := fp.Hash(msg, dst, 2) 111 if err != nil { 112 return res, err 113 } 114 var t fptower.E4 115 t.B0.A0.Set(&_t[0]) 116 t.B1.A0.Set(&_t[1]) 117 res = MapToG2(t) 118 return res, nil 119 } 120 121 // HashToG2 maps an fp.Element to a point on the curve using the Shallue and van de Woestijne map 122 // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-3 123 func HashToG2(msg, dst []byte) (G2Affine, error) { 124 var res G2Affine 125 u, err := fp.Hash(msg, dst, 4) 126 if err != nil { 127 return res, err 128 } 129 var u0, u1 fptower.E4 130 u0.B0.A0.Set(&u[0]) 131 u0.B1.A0.Set(&u[1]) 132 u1.B0.A0.Set(&u[2]) 133 u1.B1.A0.Set(&u[3]) 134 Q0 := MapToG2(u0) 135 Q1 := MapToG2(u1) 136 var _Q0, _Q1, _res G2Jac 137 _Q0.FromAffine(&Q0) 138 _Q1.FromAffine(&Q1) 139 _res.Set(&_Q1).AddAssign(&_Q0) 140 res.FromJacobian(&_res) 141 return res, nil 142 } 143 144 // returns false if u>-u when seen as a bigInt 145 func sign0(u fp.Element) bool { 146 return !u.LexicographicallyLargest() 147 }