github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/hash_to_g1.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 bls12381 18 19 import ( 20 "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" 21 22 "math/big" 23 ) 24 25 //Note: This only works for simple extensions 26 27 func g1IsogenyXNumerator(dst *fp.Element, x *fp.Element) { 28 g1EvalPolynomial(dst, 29 false, 30 []fp.Element{ 31 {5555391298090832668, 1871845530032595596, 4551034694774233518, 2584197799339864836, 15085749040064757844, 654075415717002996}, 32 {9910598932128054667, 4357765064159749802, 1555960221863322426, 9671461638228026285, 1275132148248838779, 507072521670460589}, 33 {11908177372061066827, 18190436643933350086, 6603102998733829542, 6581045210674032871, 16099974426311393401, 541581077397919012}, 34 {5282195870529824577, 12365729195083706401, 2807246122435955773, 332702220601507168, 7339422050895811209, 1050416448951884523}, 35 {10443415753526299973, 8852419397684277637, 1088333252544296036, 1174353327457337436, 1626144519293139599, 716651429285276662}, 36 {7916646322956281527, 11909818257232418749, 1455301921509471421, 3317627683558310107, 12693445337245173919, 1798273032850409769}, 37 {2577731109215284733, 8810166123993386985, 3186592767751348067, 15050850291391518479, 18435652654155870871, 1330813445865859326}, 38 {8787912969482053798, 9653629252694769025, 1358451377919714320, 16331599695590198629, 13519934665722691825, 628078949001449512}, 39 {16605411443261943819, 9536014432113026165, 8685402948537367476, 16291074259433785035, 407185289045737198, 713426768049972652}, 40 {1001421273809907975, 724433776290697394, 16309429154639760781, 10003715605277815375, 307249038158020985, 688008371043525493}, 41 {16622893420529658311, 18333652517857227637, 2139173376235292830, 16496634502105693419, 5355299366650241487, 382770009771704860}, 42 {8276255265012938363, 9997870203437298645, 16819210142450232135, 5062450688048499179, 12776432501206859311, 1778476024187613533}, 43 }, 44 x) 45 } 46 47 func g1IsogenyXDenominator(dst *fp.Element, x *fp.Element) { 48 g1EvalPolynomial(dst, 49 true, 50 []fp.Element{ 51 {13358415881952098629, 12009257493157516192, 13928884382876484932, 12988314785833227070, 11244145530317148182, 100673949996487007}, 52 {2533162896381624793, 10578896196504721258, 4263020647280931071, 1255899686249737875, 17097124965295857733, 590960935246623182}, 53 {10990404485039254780, 5344458621503091696, 1718862119039451458, 11600049052019063549, 18389973225607751698, 1092616849767867362}, 54 {16377845895484993601, 15314247056264135931, 14543008873173635408, 4875476272346940127, 2030129768648768484, 1297689274107773964}, 55 {6376927397170316667, 1460555178565443615, 18156708192400235081, 14761117739963869762, 8361091377443400626, 1421233557303902229}, 56 {18127417459170613536, 5353764292720778676, 858818813615405862, 3528937506143354306, 12604964186779349896, 489837025077541867}, 57 {15285065477075910543, 3650488990300576179, 7274499670465195193, 16100555180954076900, 7580582425312971905, 896074979407586822}, 58 {7582945168915351799, 2506680954090651888, 10272835934257987876, 9924916350558121763, 13577194922650729507, 1698254565890367778}, 59 {2009730524583761661, 11053280693947850663, 14409256190409559425, 3658799329773368860, 13529638021208614900, 869243908766415668}, 60 {11058048790650732295, 7059501760293999296, 6596812464094265283, 14567744481299745071, 1591898617514919697, 1344004358835331304}, 61 }, 62 x) 63 } 64 65 func g1IsogenyYNumerator(dst *fp.Element, x *fp.Element, y *fp.Element) { 66 var _dst fp.Element 67 g1EvalPolynomial(&_dst, 68 false, 69 []fp.Element{ 70 {3122824077082063463, 2111517899915568999, 14844585557031220083, 14713720721132803039, 9041847780307969683, 950267513573868304}, 71 {11079511902567680319, 18338468344530008184, 6769016392463638666, 1504264063027988936, 8098359051856762276, 760455062874047829}, 72 {1430247552210236986, 3854575382974307965, 14917507996414511245, 207936139448560, 9498310774218301406, 1438631746617682181}, 73 {6654065794071117243, 2928282753802966791, 4144383358731160429, 12673586709493869907, 12918170109018188791, 844088361957958231}, 74 {6416330705244672319, 3552017270878949117, 7777490944331917312, 7917192495177481567, 7271851377118683537, 253926972271069325}, 75 {11903306495973637341, 11622313950541285762, 17991208474928993001, 12280964980743791783, 14941570282955772167, 143516344770893715}, 76 {7324386472845891920, 16310961984705608217, 14050364318273732029, 410622978843904432, 13407944087243235067, 570579643952782879}, 77 {10655681039374273828, 3913226275392147601, 9613292388335178165, 11852815148890010639, 17652581670569921892, 780578093363976825}, 78 {10454026283255684948, 15005802245309313587, 4420421943175638630, 18052347756729021570, 12181908985148691767, 1485233717472293779}, 79 {5056344670784885274, 15896288289018563095, 11120951801157184493, 7250506164525313606, 9295677455526059106, 1757175036496698059}, 80 {417067620545670182, 113740147118943311, 7666319924200602156, 1469963335415292317, 13482947512490784447, 1353298443678343909}, 81 {13069093794065563159, 18364685236451803588, 2235996605706292724, 1007629142299662669, 4077244143222018961, 162586537120788900}, 82 {12976751790971550752, 10256454045927919861, 8968423978443605586, 91636529236982767, 9459527627289574163, 949550897353139410}, 83 {10595118024452621845, 8010256778549625402, 10333144214150401956, 17682229685967587631, 8235697699445463546, 317883997785997129}, 84 {16894283457285346118, 10513943172407809423, 4685513162956315481, 11558261883362075118, 574375951146893083, 1159440548124233311}, 85 {9739780494108151959, 17207219630538774058, 553911396609642498, 6085929320386029624, 14175410874026216616, 1183751611824804793}, 86 }, 87 x) 88 89 dst.Mul(&_dst, y) 90 } 91 92 func g1IsogenyYDenominator(dst *fp.Element, x *fp.Element) { 93 g1EvalPolynomial(dst, 94 true, 95 []fp.Element{ 96 {16963992846030154524, 1796759822929186144, 15995221960860457854, 8232142361908220707, 5977498266010213481, 759868220591477233}, 97 {7019489280640006651, 8025136855967848721, 17464762292772824538, 4490335113250743896, 7652702793653159798, 1129822927746498110}, 98 {3164260796573156764, 2639884922337322818, 1251365706181388855, 13142429936036186189, 359878619957828340, 126848055205862465}, 99 {17472832885692408710, 9911075278795900735, 2614390623136861791, 14474775734428698630, 6462878218464609418, 1225960780180864957}, 100 {3586995257703132870, 2143554115308730112, 15207899356205612465, 4372523065560113828, 12811868595146042778, 307251632623424763}, 101 {14298637377310410728, 10963101290308221781, 8192510423058716701, 1175370967867267532, 1029599188863854120, 678981456155013844}, 102 {11149806480082726900, 3664985661428410608, 18095361538178773836, 14174906593575241395, 15305104369759711886, 901234928011491053}, 103 {4727074327869776987, 15736954329525418288, 14642679026711520511, 11429849039208981702, 17333567062758618213, 951235897335772166}, 104 {9130114290642375589, 14069725355798443159, 6621984191700563591, 270173975669947883, 6218390495944243859, 1077419361593130421}, 105 {9144875514986933294, 16561351410666797616, 8591333879886582656, 15059370240386191395, 7834396448114781869, 946553772269403391}, 106 {17809450171377747225, 15896956440537434491, 8451524482089653422, 1694507265233574136, 18224201536921880842, 317503425606567070}, 107 {13940503876759740187, 8772047862193200131, 6080360161890657205, 7935486160089058373, 9407473295146243021, 1255078947940629503}, 108 {1160821217138360586, 13542760608074182996, 11595911004531652098, 18158686636947034451, 13330657138280564947, 1773960737279760188}, 109 {9132548444917292754, 16464415422105000789, 6319313500251671073, 12727658548847517900, 10985275115076354035, 1431541893474124246}, 110 {662485641082390837, 260809847827618849, 6177381409359357075, 18231947741742261351, 18128540110746580014, 1079107229429227022}, 111 }, 112 x) 113 } 114 115 func g1Isogeny(p *G1Affine) { 116 117 den := make([]fp.Element, 2) 118 119 g1IsogenyYDenominator(&den[1], &p.X) 120 g1IsogenyXDenominator(&den[0], &p.X) 121 122 g1IsogenyYNumerator(&p.Y, &p.X, &p.Y) 123 g1IsogenyXNumerator(&p.X, &p.X) 124 125 den = fp.BatchInvert(den) 126 127 p.X.Mul(&p.X, &den[0]) 128 p.Y.Mul(&p.Y, &den[1]) 129 } 130 131 // g1SqrtRatio computes the square root of u/v and returns 0 iff u/v was indeed a quadratic residue 132 // if not, we get sqrt(Z * u / v). Recall that Z is non-residue 133 // If v = 0, u/v is meaningless and the output is unspecified, without raising an error. 134 // The main idea is that since the computation of the square root involves taking large powers of u/v, the inversion of v can be avoided 135 func g1SqrtRatio(z *fp.Element, u *fp.Element, v *fp.Element) uint64 { 136 // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-optimized-sqrt_ratio-for-q- (3 mod 4) 137 var tv1 fp.Element 138 tv1.Square(v) // 1. tv1 = v² 139 var tv2 fp.Element 140 tv2.Mul(u, v) // 2. tv2 = u * v 141 tv1.Mul(&tv1, &tv2) // 3. tv1 = tv1 * tv2 142 143 var y1 fp.Element 144 { 145 var c1 big.Int 146 // c1 = 1000602388805416848354447456433976039139220704984751971333014534031007912622709466110671907282253916009473568139946 147 c1.SetBytes([]byte{6, 128, 68, 122, 142, 95, 249, 166, 146, 198, 233, 237, 144, 210, 235, 53, 217, 29, 210, 225, 60, 225, 68, 175, 217, 204, 52, 168, 61, 172, 61, 137, 7, 170, 255, 255, 172, 84, 255, 255, 238, 127, 191, 255, 255, 255, 234, 170}) // c1 = (q - 3) / 4 # Integer arithmetic 148 149 y1.Exp(tv1, &c1) // 4. y1 = tv1ᶜ¹ 150 } 151 152 y1.Mul(&y1, &tv2) // 5. y1 = y1 * tv2 153 154 var y2 fp.Element 155 // c2 = sqrt(-Z) 156 tv3 := fp.Element{17544630987809824292, 17306709551153317753, 8299808889594647786, 5930295261504720397, 675038575008112577, 167386374569371918} 157 y2.Mul(&y1, &tv3) // 6. y2 = y1 * c2 158 tv3.Square(&y1) // 7. tv3 = y1² 159 tv3.Mul(&tv3, v) // 8. tv3 = tv3 * v 160 isQNr := tv3.NotEqual(u) // 9. isQR = tv3 == u 161 z.Select(int(isQNr), &y1, &y2) // 10. y = CMOV(y2, y1, isQR) 162 return isQNr 163 } 164 165 // g1MulByZ multiplies x by [11] and stores the result in z 166 func g1MulByZ(z *fp.Element, x *fp.Element) { 167 168 res := *x 169 170 res.Double(&res) 171 res.Double(&res) 172 res.Add(&res, x) 173 res.Double(&res) 174 res.Add(&res, x) 175 176 *z = res 177 } 178 179 // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-simplified-swu-method 180 // MapToCurve1 implements the SSWU map 181 // No cofactor clearing or isogeny 182 func MapToCurve1(u *fp.Element) G1Affine { 183 184 var sswuIsoCurveCoeffA = fp.Element{3415322872136444497, 9675504606121301699, 13284745414851768802, 2873609449387478652, 2897906769629812789, 1536947672689614213} 185 var sswuIsoCurveCoeffB = fp.Element{18129637713272545760, 11144507692959411567, 10108153527111632324, 9745270364868568433, 14587922135379007624, 469008097655535723} 186 187 var tv1 fp.Element 188 tv1.Square(u) // 1. tv1 = u² 189 190 //mul tv1 by Z 191 g1MulByZ(&tv1, &tv1) // 2. tv1 = Z * tv1 192 193 var tv2 fp.Element 194 tv2.Square(&tv1) // 3. tv2 = tv1² 195 tv2.Add(&tv2, &tv1) // 4. tv2 = tv2 + tv1 196 197 var tv3 fp.Element 198 var tv4 fp.Element 199 tv4.SetOne() 200 tv3.Add(&tv2, &tv4) // 5. tv3 = tv2 + 1 201 tv3.Mul(&tv3, &sswuIsoCurveCoeffB) // 6. tv3 = B * tv3 202 203 tv2NZero := g1NotZero(&tv2) 204 205 // tv4 = Z 206 tv4 = fp.Element{9830232086645309404, 1112389714365644829, 8603885298299447491, 11361495444721768256, 5788602283869803809, 543934104870762216} 207 208 tv2.Neg(&tv2) 209 tv4.Select(int(tv2NZero), &tv4, &tv2) // 7. tv4 = CMOV(Z, -tv2, tv2 != 0) 210 tv4.Mul(&tv4, &sswuIsoCurveCoeffA) // 8. tv4 = A * tv4 211 212 tv2.Square(&tv3) // 9. tv2 = tv3² 213 214 var tv6 fp.Element 215 tv6.Square(&tv4) // 10. tv6 = tv4² 216 217 var tv5 fp.Element 218 tv5.Mul(&tv6, &sswuIsoCurveCoeffA) // 11. tv5 = A * tv6 219 220 tv2.Add(&tv2, &tv5) // 12. tv2 = tv2 + tv5 221 tv2.Mul(&tv2, &tv3) // 13. tv2 = tv2 * tv3 222 tv6.Mul(&tv6, &tv4) // 14. tv6 = tv6 * tv4 223 224 tv5.Mul(&tv6, &sswuIsoCurveCoeffB) // 15. tv5 = B * tv6 225 tv2.Add(&tv2, &tv5) // 16. tv2 = tv2 + tv5 226 227 var x fp.Element 228 x.Mul(&tv1, &tv3) // 17. x = tv1 * tv3 229 230 var y1 fp.Element 231 gx1NSquare := g1SqrtRatio(&y1, &tv2, &tv6) // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6) 232 233 var y fp.Element 234 y.Mul(&tv1, u) // 19. y = tv1 * u 235 236 y.Mul(&y, &y1) // 20. y = y * y1 237 238 x.Select(int(gx1NSquare), &tv3, &x) // 21. x = CMOV(x, tv3, is_gx1_square) 239 y.Select(int(gx1NSquare), &y1, &y) // 22. y = CMOV(y, y1, is_gx1_square) 240 241 y1.Neg(&y) 242 y.Select(int(g1Sgn0(u)^g1Sgn0(&y)), &y, &y1) 243 244 // 23. e1 = sgn0(u) == sgn0(y) 245 // 24. y = CMOV(-y, y, e1) 246 247 x.Div(&x, &tv4) // 25. x = x / tv4 248 249 return G1Affine{x, y} 250 } 251 252 func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *fp.Element) { 253 dst := coefficients[len(coefficients)-1] 254 255 if monic { 256 dst.Add(&dst, x) 257 } 258 259 for i := len(coefficients) - 2; i >= 0; i-- { 260 dst.Mul(&dst, x) 261 dst.Add(&dst, &coefficients[i]) 262 } 263 264 z.Set(&dst) 265 } 266 267 // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields 268 // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign 269 // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function 270 // The sign of an element is not obviously related to that of its Montgomery form 271 func g1Sgn0(z *fp.Element) uint64 { 272 273 nonMont := z.Bits() 274 275 // m == 1 276 return nonMont[0] % 2 277 278 } 279 280 // MapToG1 invokes the SSWU map, and guarantees that the result is in g1 281 func MapToG1(u fp.Element) G1Affine { 282 res := MapToCurve1(&u) 283 //this is in an isogenous curve 284 g1Isogeny(&res) 285 res.ClearCofactor(&res) 286 return res 287 } 288 289 // EncodeToG1 hashes a message to a point on the G1 curve using the SSWU map. 290 // It is faster than HashToG1, but the result is not uniformly distributed. Unsuitable as a random oracle. 291 // dst stands for "domain separation tag", a string unique to the construction using the hash function 292 // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap 293 func EncodeToG1(msg, dst []byte) (G1Affine, error) { 294 295 var res G1Affine 296 u, err := fp.Hash(msg, dst, 1) 297 if err != nil { 298 return res, err 299 } 300 301 res = MapToCurve1(&u[0]) 302 303 //this is in an isogenous curve 304 g1Isogeny(&res) 305 res.ClearCofactor(&res) 306 return res, nil 307 } 308 309 // HashToG1 hashes a message to a point on the G1 curve using the SSWU map. 310 // Slower than EncodeToG1, but usable as a random oracle. 311 // dst stands for "domain separation tag", a string unique to the construction using the hash function 312 // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap 313 func HashToG1(msg, dst []byte) (G1Affine, error) { 314 u, err := fp.Hash(msg, dst, 2*1) 315 if err != nil { 316 return G1Affine{}, err 317 } 318 319 Q0 := MapToCurve1(&u[0]) 320 Q1 := MapToCurve1(&u[1]) 321 322 //TODO (perf): Add in E' first, then apply isogeny 323 g1Isogeny(&Q0) 324 g1Isogeny(&Q1) 325 326 var _Q0, _Q1 G1Jac 327 _Q0.FromAffine(&Q0) 328 _Q1.FromAffine(&Q1).AddAssign(&_Q0) 329 330 _Q1.ClearCofactor(&_Q1) 331 332 Q1.FromJacobian(&_Q1) 333 return Q1, nil 334 } 335 336 func g1NotZero(x *fp.Element) uint64 { 337 338 return x[0] | x[1] | x[2] | x[3] | x[4] | x[5] 339 340 }