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 }