github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-761/internal/fptower/e6_pairing.go (about) 1 package fptower 2 3 import "github.com/consensys/gnark-crypto/ecc/bw6-761/fp" 4 5 func (z *E6) nSquare(n int) { 6 for i := 0; i < n; i++ { 7 z.CyclotomicSquare(z) 8 } 9 } 10 11 func (z *E6) nSquareCompressed(n int) { 12 for i := 0; i < n; i++ { 13 z.CyclotomicSquareCompressed(z) 14 } 15 } 16 17 // ExptMinus1 set z to x^(t-1) in E6 and return z 18 // t-1 = 91893752504881257682351033800651177983 19 func (z *E6) ExptMinus1(x *E6) *E6 { 20 21 var result, x33 E6 22 result.Set(x) 23 result.nSquare(5) 24 result.Mul(&result, x) 25 x33.Set(&result) 26 result.nSquare(7) 27 result.Mul(&result, &x33) 28 result.nSquare(4) 29 result.Mul(&result, x) 30 result.CyclotomicSquare(&result) 31 result.Mul(&result, x) 32 result.nSquareCompressed(46) 33 result.DecompressKarabina(&result) 34 z.Set(&result) 35 36 return z 37 } 38 39 // ExptMinus1Square set z to x^{(t-1)²} in E6 and return z 40 // (t-1)² = 91893752504881257682351033800651177984 41 func (z *E6) ExptMinus1Square(x *E6) *E6 { 42 var result, t0, t1, t2 E6 43 44 result.Set(x) 45 result.CyclotomicSquare(&result) 46 t0.Mul(x, &result) 47 t1.CyclotomicSquare(&t0) 48 t0.Mul(&t0, &t1) 49 result.Mul(&result, &t0) 50 t1.Mul(&t1, &result) 51 t0.Mul(&t0, &t1) 52 t2.CyclotomicSquare(&t0) 53 t2.Mul(&t1, &t2) 54 t0.Mul(&t0, &t2) 55 t2.nSquare(7) 56 t1.Mul(&t1, &t2) 57 t1.nSquare(11) 58 t1.Mul(&t0, &t1) 59 t1.nSquare(9) 60 t0.Mul(&t0, &t1) 61 t0.CyclotomicSquare(&t0) 62 result.Mul(&result, &t0) 63 result.nSquareCompressed(92) 64 result.DecompressKarabina(&result) 65 z.Set(&result) 66 67 return z 68 } 69 70 // Expt set z to x^t in E6 and return z 71 // t = 91893752504881257682351033800651177984 72 func (z *E6) Expt(x *E6) *E6 { 73 var result E6 74 75 result.ExptMinus1(x) 76 result.Mul(&result, x) 77 z.Set(&result) 78 79 return z 80 } 81 82 // ExptPlus1 set z to x^(t+1) in E6 and return z 83 // t+1 = 91893752504881257682351033800651177985 84 func (z *E6) ExptPlus1(x *E6) *E6 { 85 var result, t E6 86 87 result.ExptMinus1(x) 88 t.CyclotomicSquare(x) 89 result.Mul(&result, &t) 90 z.Set(&result) 91 92 return z 93 } 94 95 // ExptMinus1Div3 set z to x^(t-1)/3 in E6 and return z 96 // (t-1)/3 = 3195374304363544576 97 func (z *E6) ExptMinus1Div3(x *E6) *E6 { 98 var result, t0 E6 99 100 result.Set(x) 101 result.CyclotomicSquare(&result) 102 result.Mul(&result, x) 103 t0.Mul(&result, x) 104 t0.CyclotomicSquare(&t0) 105 result.Mul(&result, &t0) 106 t0.Set(&result) 107 t0.nSquare(7) 108 result.Mul(&result, &t0) 109 result.nSquare(5) 110 result.Mul(&result, x) 111 result.nSquareCompressed(46) 112 result.DecompressKarabina(&result) 113 z.Set(&result) 114 115 return z 116 } 117 118 // Expc1 set z to z^c1 in E6 and return z 119 // ht, hy = 13, 9 120 // c1 = (ht+hy)/2 = 11 121 func (z *E6) Expc1(x *E6) *E6 { 122 var result, t0 E6 123 124 result.CyclotomicSquare(x) 125 result.Mul(&result, x) 126 t0.Mul(x, &result) 127 t0.CyclotomicSquare(&t0) 128 result.Mul(&result, &t0) 129 z.Set(&result) 130 131 return z 132 } 133 134 // Expc2 set z to z^c2 in E6 and return z 135 // ht, hy = 13, 9 136 // c2 = (ht**2+3*hy**2)/4 = 103 137 func (z *E6) Expc2(x *E6) *E6 { 138 var result, t0 E6 139 140 result.CyclotomicSquare(x) 141 result.Mul(&result, x) 142 t0.Set(&result) 143 t0.nSquare(4) 144 result.Mul(&result, &t0) 145 result.CyclotomicSquare(&result) 146 result.Mul(&result, x) 147 z.Set(&result) 148 149 return z 150 } 151 152 // MulBy014 multiplication by sparse element (c0,c1,0,0,c4,0) 153 func (z *E6) MulBy014(c0, c1, c4 *fp.Element) *E6 { 154 155 var a, b E3 156 var d fp.Element 157 158 a.Set(&z.B0) 159 a.MulBy01(c0, c1) 160 161 b.Set(&z.B1) 162 b.MulBy1(c4) 163 d.Add(c1, c4) 164 165 z.B1.Add(&z.B1, &z.B0) 166 z.B1.MulBy01(c0, &d) 167 z.B1.Sub(&z.B1, &a) 168 z.B1.Sub(&z.B1, &b) 169 z.B0.MulByNonResidue(&b) 170 z.B0.Add(&z.B0, &a) 171 172 return z 173 } 174 175 // MulBy01 multiplication by sparse element (c0, c1, 0, 0, 1) 176 func (z *E6) MulBy01(c0, c1 *fp.Element) *E6 { 177 178 var a, b E3 179 var d fp.Element 180 181 a.Set(&z.B0) 182 a.MulBy01(c0, c1) 183 184 b.MulByNonResidue(&z.B1) 185 d.SetOne().Add(c1, &d) 186 187 z.B1.Add(&z.B1, &z.B0) 188 z.B1.MulBy01(c0, &d) 189 z.B1.Sub(&z.B1, &a) 190 z.B1.Sub(&z.B1, &b) 191 z.B0.MulByNonResidue(&b) 192 z.B0.Add(&z.B0, &a) 193 194 return z 195 } 196 197 // Mul01By01 multiplication of sparse element (c0,c1,0,0,1,0) by sparse element (d0,d1,0,0,1,0) 198 func Mul01By01(d0, d1, c0, c1 *fp.Element) [5]fp.Element { 199 var z00, tmp, x0, x1, x4, x04, x01, x14 fp.Element 200 x0.Mul(c0, d0) 201 x1.Mul(c1, d1) 202 x4.SetOne() 203 x04.Add(d0, c0) 204 tmp.Add(c0, c1) 205 x01.Add(d0, d1). 206 Mul(&x01, &tmp). 207 Sub(&x01, &x0). 208 Sub(&x01, &x1) 209 x14.Add(d1, c1) 210 211 z00.MulByNonResidue(&x4). 212 Add(&z00, &x0) 213 214 return [5]fp.Element{z00, x01, x1, x04, x14} 215 } 216 217 // Mul014By014 multiplication of sparse element (c0,c1,0,0,c4,0) by sparse element (d0,d1,0,0,d4,0) 218 func Mul014By014(d0, d1, d4, c0, c1, c4 *fp.Element) [5]fp.Element { 219 var z00, tmp, x0, x1, x4, x04, x01, x14 fp.Element 220 x0.Mul(c0, d0) 221 x1.Mul(c1, d1) 222 x4.Mul(c4, d4) 223 tmp.Add(c0, c4) 224 x04.Add(d0, d4). 225 Mul(&x04, &tmp). 226 Sub(&x04, &x0). 227 Sub(&x04, &x4) 228 tmp.Add(c0, c1) 229 x01.Add(d0, d1). 230 Mul(&x01, &tmp). 231 Sub(&x01, &x0). 232 Sub(&x01, &x1) 233 tmp.Add(c1, c4) 234 x14.Add(d1, d4). 235 Mul(&x14, &tmp). 236 Sub(&x14, &x1). 237 Sub(&x14, &x4) 238 239 z00.MulByNonResidue(&x4). 240 Add(&z00, &x0) 241 242 return [5]fp.Element{z00, x01, x1, x04, x14} 243 } 244 245 // MulBy01245 multiplies z by an E12 sparse element of the form (x0, x1, x2, 0, x4, x5) 246 func (z *E6) MulBy01245(x *[5]fp.Element) *E6 { 247 var c1, a, b, c, z0, z1 E3 248 c0 := &E3{A0: x[0], A1: x[1], A2: x[2]} 249 c1.A1 = x[3] 250 c1.A2 = x[4] 251 a.Add(&z.B0, &z.B1) 252 b.Add(c0, &c1) 253 a.Mul(&a, &b) 254 b.Mul(&z.B0, c0) 255 c.Set(&z.B1).MulBy12(&x[3], &x[4]) 256 z1.Sub(&a, &b) 257 z1.Sub(&z1, &c) 258 z0.MulByNonResidue(&c) 259 z0.Add(&z0, &b) 260 261 z.B0 = z0 262 z.B1 = z1 263 264 return z 265 }