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