github.com/emmansun/gmsm@v0.29.1/sm9/bn256/bn_pair_b6.go (about)

     1  package bn256
     2  
     3  // (ret.x t + ret.y) * ((cs)t + (bs+a))
     4  //= ((ret.x * (bs+a))+ret.y*cs) t + (ret.y*(bs+a) + ret.x*cs*s)
     5  //= (ret.x*bs + ret.x*a + ret.y*cs) t + (ret.y*bs + ret.x*cs*s + ret.y * a)
     6  //ret.x = (ret.x + ret.y)(cs + bs + a) - ret.y(bs+a) - ret.x*cs
     7  //ret.y = ret.y(bs+a) + ret.x*cs *s
     8  func mulLineB6(ret *gfP12b6, a, b, c *gfP2) {
     9  	a2 := &gfP6{}
    10  	a2.y.Set(b)
    11  	a2.z.Set(a)
    12  	a2.Mul(&ret.y, a2)
    13  	t3 := &gfP6{}
    14  	t3.MulScalar(&ret.x, c).MulS(t3)
    15  
    16  	t := (&gfP2{}).Add(b, c)
    17  	t2 := &gfP6{}
    18  	t2.y.Set(t)
    19  	t2.z.Set(a)
    20  	ret.x.Add(&ret.x, &ret.y)
    21  
    22  	ret.y.Set(t3)
    23  
    24  	ret.x.Mul(&ret.x, t2).Sub(&ret.x, a2).Sub(&ret.x, &ret.y)
    25  
    26  	ret.y.MulS(&ret.y)
    27  	ret.y.Add(&ret.y, a2)
    28  }
    29  
    30  // R-ate Pairing G2 x G1 -> GT
    31  //
    32  // P is a point of order q in G1. Q(x,y) is a point of order q in G2.
    33  // Note that Q is a point on the sextic twist of the curve over Fp^2, P(x,y) is a point on the
    34  // curve over the base field Fp
    35  //
    36  func millerB6(q *twistPoint, p *curvePoint) *gfP12b6 {
    37  	ret := (&gfP12b6{}).SetOne()
    38  
    39  	aAffine := &twistPoint{}
    40  	aAffine.Set(q)
    41  	aAffine.MakeAffine()
    42  
    43  	minusA := &twistPoint{}
    44  	minusA.Neg(aAffine)
    45  
    46  	bAffine := &curvePoint{}
    47  	bAffine.Set(p)
    48  	bAffine.MakeAffine()
    49  
    50  	r := &twistPoint{}
    51  	r.Set(aAffine)
    52  
    53  	r2 := (&gfP2{}).Square(&aAffine.y)
    54  
    55  	a, b, c := &gfP2{}, &gfP2{}, &gfP2{}
    56  	newR := &twistPoint{}
    57  	var tmpR *twistPoint
    58  	for i := len(sixUPlus2NAF) - 1; i > 0; i-- {
    59  		lineFunctionDouble(r, newR, bAffine, a, b, c)
    60  		if i != len(sixUPlus2NAF)-1 {
    61  			ret.Square(ret)
    62  		}
    63  		mulLineB6(ret, a, b, c)
    64  		tmpR = r
    65  		r = newR
    66  		newR = tmpR
    67  		switch sixUPlus2NAF[i-1] {
    68  		case 1:
    69  			lineFunctionAdd(r, aAffine, newR, bAffine, r2, a, b, c)
    70  		case -1:
    71  			lineFunctionAdd(r, minusA, newR, bAffine, r2, a, b, c)
    72  		default:
    73  			continue
    74  		}
    75  
    76  		mulLineB6(ret, a, b, c)
    77  		tmpR = r
    78  		r = newR
    79  		newR = tmpR
    80  	}
    81  
    82  	// In order to calculate Q1 we have to convert q from the sextic twist
    83  	// to the full GF(p^12) group, apply the Frobenius there, and convert
    84  	// back.
    85  	//
    86  	// The twist isomorphism is (x', y') -> (x*β^(-1/3), y*β^(-1/2)). If we consider just
    87  	// x for a moment, then after applying the Frobenius, we have x̄*β^(-p/3)
    88  	// where x̄ is the conjugate of x.	If we are going to apply the inverse
    89  	// isomorphism we need a value with a single coefficient of β^(-1/3) so we
    90  	// rewrite this as x̄*β^((-p+1)/3)*β^(-1/3).
    91  	//
    92  	// A similar argument can be made for the y value.
    93  	q1 := &twistPoint{}
    94  	q1.x.Conjugate(&aAffine.x)
    95  	q1.x.MulScalar(&q1.x, betaToNegPPlus1Over3)
    96  	q1.y.Conjugate(&aAffine.y)
    97  	q1.y.MulScalar(&q1.y, betaToNegPPlus1Over2)
    98  	q1.z.SetOne()
    99  	q1.t.SetOne()
   100  
   101  	minusQ2 := &twistPoint{}
   102  	minusQ2.x.Set(&aAffine.x)
   103  	minusQ2.x.MulScalar(&minusQ2.x, betaToNegP2Plus1Over3)
   104  	minusQ2.y.Neg(&aAffine.y)
   105  	minusQ2.y.MulScalar(&minusQ2.y, betaToNegP2Plus1Over2)
   106  	minusQ2.z.SetOne()
   107  	minusQ2.t.SetOne()
   108  
   109  	r2.Square(&q1.y)
   110  	lineFunctionAdd(r, q1, newR, bAffine, r2, a, b, c)
   111  	mulLineB6(ret, a, b, c)
   112  	tmpR = r
   113  	r = newR
   114  	newR = tmpR
   115  
   116  	r2.Square(&minusQ2.y)
   117  	lineFunctionAdd(r, minusQ2, newR, bAffine, r2, a, b, c)
   118  	mulLineB6(ret, a, b, c)
   119  
   120  	return ret
   121  }
   122  
   123  func pairingB6(a *twistPoint, b *curvePoint) *gfP12 {
   124  	e := millerB6(a, b)
   125  	ret := finalExponentiationB6(e)
   126  
   127  	if a.IsInfinity() || b.IsInfinity() {
   128  		ret.SetOne()
   129  	}
   130  	return ret.ToGfP12()
   131  }
   132  
   133  // finalExponentiation computes the (p¹²-1)/Order-th power of an element of
   134  // GF(p¹²) to obtain an element of GT. https://eprint.iacr.org/2007/390.pdf
   135  // http://cryptojedi.org/papers/dclxvi-20100714.pdf
   136  func finalExponentiationB6(in *gfP12b6) *gfP12b6 {
   137  	t1 := &gfP12b6{}
   138  
   139  	// This is the p^6-Frobenius
   140  	t1.x.Neg(&in.x)
   141  	t1.y.Set(&in.y)
   142  
   143  	inv := &gfP12b6{}
   144  	inv.Invert(in)
   145  	t1.Mul(t1, inv)
   146  
   147  	t2 := inv.FrobeniusP2(t1) // reuse inv
   148  	t1.Mul(t1, t2)
   149  
   150  	fp := (&gfP12b6{}).Frobenius(t1)
   151  	fp2 := (&gfP12b6{}).FrobeniusP2(t1)
   152  	fp3 := (&gfP12b6{}).Frobenius(fp2)
   153  
   154  	y0 := &gfP12b6{}
   155  	y0.MulNC(fp, fp2).Mul(y0, fp3)
   156  
   157  	// reuse fp, fp2, fp3 local variables
   158  	fu := fp.Cyclo6PowToU(t1)
   159  	fu2 := fp2.Cyclo6PowToU(fu)
   160  	fu3 := fp3.Cyclo6PowToU(fu2)
   161  
   162  	y3 := (&gfP12b6{}).Frobenius(fu)
   163  	fu2p := (&gfP12b6{}).Frobenius(fu2)
   164  	fu3p := (&gfP12b6{}).Frobenius(fu3)
   165  	y2 := (&gfP12b6{}).FrobeniusP2(fu2)
   166  
   167  	y1 := (&gfP12b6{}).Conjugate(t1)
   168  	y5 := (&gfP12b6{}).Conjugate(fu2)
   169  	y3.Conjugate(y3)
   170  	y4 := (&gfP12b6{}).MulNC(fu, fu2p)
   171  	y4.Conjugate(y4)
   172  
   173  	y6 := (&gfP12b6{}).MulNC(fu3, fu3p)
   174  	y6.Conjugate(y6)
   175  
   176  	t0 := (&gfP12b6{}).Cyclo6SquareNC(y6)
   177  	t0.Mul(t0, y4).Mul(t0, y5)
   178  	t1.Mul(y3, y5).Mul(t1, t0)
   179  	t0.Mul(t0, y2)
   180  	t1.Cyclo6Square(t1).Mul(t1, t0).Cyclo6Square(t1)
   181  	t0.Mul(t1, y1)
   182  	t1.Mul(t1, y0)
   183  	t0.Cyclo6Square(t0).Mul(t0, t1)
   184  
   185  	return t0
   186  }