github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-761/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 bw6761
    18  
    19  import (
    20  	"github.com/consensys/gnark-crypto/ecc/bw6-761/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  			{8909527437822417859, 3882721843441849971, 10272758549140236519, 14003949960675888070, 3082674948893537730, 15057121805406331995, 9473729116041321980, 4728985833820774787, 8655877921490901299, 4190069830971789310, 5954844214359654504, 3167048922498340},
    32  			{18108974101656748848, 2338690158884275892, 6508602482182596491, 4145012576748966774, 3414660410706516893, 2573833883260883150, 6164918126664265221, 14548675305047459086, 16639788212446610270, 18398701356395340891, 6095608892147913870, 52477293239851844},
    33  			{9054487050828374424, 10392717116296913754, 3254301241091298245, 11295878325229259195, 1707330205353258446, 10510288978485217383, 3082459063332132610, 7274337652523729543, 17543266143078080943, 9199350678197670445, 3047804446073956935, 26238646619925922},
    34  		},
    35  		x)
    36  }
    37  
    38  func g1IsogenyXDenominator(dst *fp.Element, x *fp.Element) {
    39  	g1EvalPolynomial(dst,
    40  		true,
    41  		[]fp.Element{
    42  			{289919226011913130, 13019990545710127566, 4409829457611675068, 13030600802816293865, 15696054586628993047, 9353078419867322391, 5664203968291172875, 5090703637405909511, 17774776443174359288, 10018561694451762270, 12632664537138156478, 46143195394855163},
    43  		},
    44  		x)
    45  }
    46  
    47  func g1IsogenyYNumerator(dst *fp.Element, x *fp.Element, y *fp.Element) {
    48  	var _dst fp.Element
    49  	g1EvalPolynomial(&_dst,
    50  		false,
    51  		[]fp.Element{
    52  			{9682176248893090322, 2627273429413213811, 1155528216520376823, 1734722477587034670, 13988724381275734601, 17289533515091656624, 2581744904959040264, 16263110058591731584, 231510300096278344, 819211016254091825, 9584860091064199543, 19904548774929241},
    53  			{14209419774307277534, 17047004024416446496, 12006050873920801753, 7382661640201664267, 5619017447097588016, 4097933930624713700, 13346346473479882378, 10676906847998820547, 18226515408490094624, 14642258392207702855, 11108762314101178010, 33023872084892202},
    54  			{8716717078775571656, 12731407275181189647, 9762903723273894736, 15440890901978225969, 5121990616059775339, 13084122861746100533, 9247377189996397831, 3376268883861637013, 15736310281815139598, 9151307960883459721, 9143413338221870806, 78715939859777766},
    55  			{4527243525414187212, 14419730595003232685, 10850522657400424930, 5647939162614629597, 10077037139531405031, 5255144489242608691, 10764601568520842113, 12860540863116640579, 17995005108393816279, 13823047375953611030, 1523902223036978467, 13119323309962961},
    56  		},
    57  		x)
    58  
    59  	dst.Mul(&_dst, y)
    60  }
    61  
    62  func g1IsogenyYDenominator(dst *fp.Element, x *fp.Element) {
    63  	g1EvalPolynomial(dst,
    64  		true,
    65  		[]fp.Element{
    66  			{2800676018270776722, 404959871884879410, 14461481433037540995, 11679465559666498996, 9481399069190242817, 18023312492583527742, 3661347334798803492, 4152305114258814443, 3867985292375803742, 13391491194096551019, 1887398969680023676, 20806804014868441},
    67  			{4201014027406165083, 9830811844682094923, 3245478075846759876, 8295826302644972687, 14222098603785364226, 8588224665165739997, 14715393039052981047, 6228457671388221664, 15025349975418481421, 1640492717435274912, 12054470491374811323, 31210206022302661},
    68  			{1690257235147301491, 3999098444797791463, 11640570174130445566, 9646961545794767555, 1990010047514562840, 18364734666159086263, 16718249672545350429, 7166856194535316732, 10485397052507485351, 16714307291500037780, 4352991985123392508, 56546597402289384},
    69  		},
    70  		x)
    71  }
    72  
    73  func g1Isogeny(p *G1Affine) {
    74  
    75  	den := make([]fp.Element, 2)
    76  
    77  	g1IsogenyYDenominator(&den[1], &p.X)
    78  	g1IsogenyXDenominator(&den[0], &p.X)
    79  
    80  	g1IsogenyYNumerator(&p.Y, &p.X, &p.Y)
    81  	g1IsogenyXNumerator(&p.X, &p.X)
    82  
    83  	den = fp.BatchInvert(den)
    84  
    85  	p.X.Mul(&p.X, &den[0])
    86  	p.Y.Mul(&p.Y, &den[1])
    87  }
    88  
    89  // g1SqrtRatio computes the square root of u/v and returns 0 iff u/v was indeed a quadratic residue
    90  // if not, we get sqrt(Z * u / v). Recall that Z is non-residue
    91  // If v = 0, u/v is meaningless and the output is unspecified, without raising an error.
    92  // 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
    93  func g1SqrtRatio(z *fp.Element, u *fp.Element, v *fp.Element) uint64 {
    94  	// https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-optimized-sqrt_ratio-for-q- (3 mod 4)
    95  	var tv1 fp.Element
    96  	tv1.Square(v) // 1. tv1 = v²
    97  	var tv2 fp.Element
    98  	tv2.Mul(u, v)       // 2. tv2 = u * v
    99  	tv1.Mul(&tv1, &tv2) // 3. tv1 = tv1 * tv2
   100  
   101  	var y1 fp.Element
   102  	{
   103  		var c1 big.Int
   104  		// c1 = 1722862596078933134849197420568914385619917228134037527378447540052405855560872934021920795822352921910216141938446653362790439780138561939837377924781325399737901274844627212593135907855899198987974925107492278210691228279767074
   105  		c1.SetBytes([]byte{72, 186, 9, 62, 224, 243, 130, 180, 97, 242, 80, 1, 62, 191, 207, 174, 73, 134, 26, 160, 116, 81, 162, 20, 160, 157, 123, 224, 33, 239, 144, 92, 30, 233, 142, 57, 97, 58, 70, 64, 243, 174, 191, 201, 109, 8, 193, 33, 162, 114, 59, 68, 190, 127, 100, 28, 119, 52, 247, 28, 250, 255, 203, 166, 40, 69, 176, 149, 153, 234, 62, 5, 131, 62, 43, 186, 188, 41, 13, 249, 164, 79, 154, 28, 0, 0, 32, 189, 39, 64, 0, 0, 0, 0, 34}) // c1 = (q - 3) / 4     # Integer arithmetic
   106  
   107  		y1.Exp(tv1, &c1) // 4. y1 = tv1ᶜ¹
   108  	}
   109  
   110  	y1.Mul(&y1, &tv2) // 5. y1 = y1 * tv2
   111  
   112  	var y2 fp.Element
   113  	// c2 = sqrt(-Z)
   114  	tv3 := fp.Element{10289215067249928212, 13987875627487618797, 10154775028297877632, 5892581882377791321, 12835424790914788634, 14963278386355512102, 10283221901563449361, 9868336211540881409, 7345304935218488881, 6998778443322886180, 9453359982570584357, 56775348355244645}
   115  	y2.Mul(&y1, &tv3)              // 6. y2 = y1 * c2
   116  	tv3.Square(&y1)                // 7. tv3 = y1²
   117  	tv3.Mul(&tv3, v)               // 8. tv3 = tv3 * v
   118  	isQNr := tv3.NotEqual(u)       // 9. isQR = tv3 == u
   119  	z.Select(int(isQNr), &y1, &y2) // 10. y = CMOV(y2, y1, isQR)
   120  	return isQNr
   121  }
   122  
   123  // g1MulByZ multiplies x by [2] and stores the result in z
   124  func g1MulByZ(z *fp.Element, x *fp.Element) {
   125  
   126  	res := *x
   127  
   128  	res.Double(&res)
   129  
   130  	*z = res
   131  }
   132  
   133  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-simplified-swu-method
   134  // MapToCurve1 implements the SSWU map
   135  // No cofactor clearing or isogeny
   136  func MapToCurve1(u *fp.Element) G1Affine {
   137  
   138  	var sswuIsoCurveCoeffA = fp.Element{12169852093062392636, 3867460573998792965, 2540986171999662608, 3377838107874487171, 6313266756742099767, 5994530928773814047, 5007141583730923456, 2345996307867737670, 7096861766432061441, 10014420324597579745, 8416419844935780388, 63340978449966806}
   139  	var sswuIsoCurveCoeffB = fp.Element{9514135687797572479, 9972495974968977338, 17954535578332286571, 7437044986470910914, 13903267017721129281, 1871129682978723308, 13401268269932482209, 739043012311877982, 12116264695643437343, 1632209977726909861, 3621981106970059143, 65605772132525947}
   140  
   141  	var tv1 fp.Element
   142  	tv1.Square(u) // 1.  tv1 = u²
   143  
   144  	//mul tv1 by Z
   145  	g1MulByZ(&tv1, &tv1) // 2.  tv1 = Z * tv1
   146  
   147  	var tv2 fp.Element
   148  	tv2.Square(&tv1)    // 3.  tv2 = tv1²
   149  	tv2.Add(&tv2, &tv1) // 4.  tv2 = tv2 + tv1
   150  
   151  	var tv3 fp.Element
   152  	var tv4 fp.Element
   153  	tv4.SetOne()
   154  	tv3.Add(&tv2, &tv4)                // 5.  tv3 = tv2 + 1
   155  	tv3.Mul(&tv3, &sswuIsoCurveCoeffB) // 6.  tv3 = B * tv3
   156  
   157  	tv2NZero := g1NotZero(&tv2)
   158  
   159  	// tv4 = Z
   160  	tv4 = fp.Element{289919226011913130, 13019990545710127566, 4409829457611675068, 13030600802816293865, 15696054586628993047, 9353078419867322391, 5664203968291172875, 5090703637405909511, 17774776443174359288, 10018561694451762270, 12632664537138156478, 46143195394855163}
   161  
   162  	tv2.Neg(&tv2)
   163  	tv4.Select(int(tv2NZero), &tv4, &tv2) // 7.  tv4 = CMOV(Z, -tv2, tv2 != 0)
   164  	tv4.Mul(&tv4, &sswuIsoCurveCoeffA)    // 8.  tv4 = A * tv4
   165  
   166  	tv2.Square(&tv3) // 9.  tv2 = tv3²
   167  
   168  	var tv6 fp.Element
   169  	tv6.Square(&tv4) // 10. tv6 = tv4²
   170  
   171  	var tv5 fp.Element
   172  	tv5.Mul(&tv6, &sswuIsoCurveCoeffA) // 11. tv5 = A * tv6
   173  
   174  	tv2.Add(&tv2, &tv5) // 12. tv2 = tv2 + tv5
   175  	tv2.Mul(&tv2, &tv3) // 13. tv2 = tv2 * tv3
   176  	tv6.Mul(&tv6, &tv4) // 14. tv6 = tv6 * tv4
   177  
   178  	tv5.Mul(&tv6, &sswuIsoCurveCoeffB) // 15. tv5 = B * tv6
   179  	tv2.Add(&tv2, &tv5)                // 16. tv2 = tv2 + tv5
   180  
   181  	var x fp.Element
   182  	x.Mul(&tv1, &tv3) // 17.   x = tv1 * tv3
   183  
   184  	var y1 fp.Element
   185  	gx1NSquare := g1SqrtRatio(&y1, &tv2, &tv6) // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)
   186  
   187  	var y fp.Element
   188  	y.Mul(&tv1, u) // 19.   y = tv1 * u
   189  
   190  	y.Mul(&y, &y1) // 20.   y = y * y1
   191  
   192  	x.Select(int(gx1NSquare), &tv3, &x) // 21.   x = CMOV(x, tv3, is_gx1_square)
   193  	y.Select(int(gx1NSquare), &y1, &y)  // 22.   y = CMOV(y, y1, is_gx1_square)
   194  
   195  	y1.Neg(&y)
   196  	y.Select(int(g1Sgn0(u)^g1Sgn0(&y)), &y, &y1)
   197  
   198  	// 23.  e1 = sgn0(u) == sgn0(y)
   199  	// 24.   y = CMOV(-y, y, e1)
   200  
   201  	x.Div(&x, &tv4) // 25.   x = x / tv4
   202  
   203  	return G1Affine{x, y}
   204  }
   205  
   206  func g1EvalPolynomial(z *fp.Element, monic bool, coefficients []fp.Element, x *fp.Element) {
   207  	dst := coefficients[len(coefficients)-1]
   208  
   209  	if monic {
   210  		dst.Add(&dst, x)
   211  	}
   212  
   213  	for i := len(coefficients) - 2; i >= 0; i-- {
   214  		dst.Mul(&dst, x)
   215  		dst.Add(&dst, &coefficients[i])
   216  	}
   217  
   218  	z.Set(&dst)
   219  }
   220  
   221  // g1Sgn0 is an algebraic substitute for the notion of sign in ordered fields
   222  // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign
   223  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function
   224  // The sign of an element is not obviously related to that of its Montgomery form
   225  func g1Sgn0(z *fp.Element) uint64 {
   226  
   227  	nonMont := z.Bits()
   228  
   229  	// m == 1
   230  	return nonMont[0] % 2
   231  
   232  }
   233  
   234  // MapToG1 invokes the SSWU map, and guarantees that the result is in g1
   235  func MapToG1(u fp.Element) G1Affine {
   236  	res := MapToCurve1(&u)
   237  	//this is in an isogenous curve
   238  	g1Isogeny(&res)
   239  	res.ClearCofactor(&res)
   240  	return res
   241  }
   242  
   243  // EncodeToG1 hashes a message to a point on the G1 curve using the SSWU map.
   244  // It is faster than HashToG1, but the result is not uniformly distributed. Unsuitable as a random oracle.
   245  // dst stands for "domain separation tag", a string unique to the construction using the hash function
   246  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap
   247  func EncodeToG1(msg, dst []byte) (G1Affine, error) {
   248  
   249  	var res G1Affine
   250  	u, err := fp.Hash(msg, dst, 1)
   251  	if err != nil {
   252  		return res, err
   253  	}
   254  
   255  	res = MapToCurve1(&u[0])
   256  
   257  	//this is in an isogenous curve
   258  	g1Isogeny(&res)
   259  	res.ClearCofactor(&res)
   260  	return res, nil
   261  }
   262  
   263  // HashToG1 hashes a message to a point on the G1 curve using the SSWU map.
   264  // Slower than EncodeToG1, but usable as a random oracle.
   265  // dst stands for "domain separation tag", a string unique to the construction using the hash function
   266  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap
   267  func HashToG1(msg, dst []byte) (G1Affine, error) {
   268  	u, err := fp.Hash(msg, dst, 2*1)
   269  	if err != nil {
   270  		return G1Affine{}, err
   271  	}
   272  
   273  	Q0 := MapToCurve1(&u[0])
   274  	Q1 := MapToCurve1(&u[1])
   275  
   276  	//TODO (perf): Add in E' first, then apply isogeny
   277  	g1Isogeny(&Q0)
   278  	g1Isogeny(&Q1)
   279  
   280  	var _Q0, _Q1 G1Jac
   281  	_Q0.FromAffine(&Q0)
   282  	_Q1.FromAffine(&Q1).AddAssign(&_Q0)
   283  
   284  	_Q1.ClearCofactor(&_Q1)
   285  
   286  	Q1.FromJacobian(&_Q1)
   287  	return Q1, nil
   288  }
   289  
   290  func g1NotZero(x *fp.Element) uint64 {
   291  
   292  	return x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | x[6] | x[7] | x[8] | x[9] | x[10] | x[11]
   293  
   294  }