github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/internal/fptower/e12_pairing.go (about) 1 package fptower 2 3 func (z *E12) nSquare(n int) { 4 for i := 0; i < n; i++ { 5 z.CyclotomicSquare(z) 6 } 7 } 8 9 func (z *E12) nSquareCompressed(n int) { 10 for i := 0; i < n; i++ { 11 z.CyclotomicSquareCompressed(z) 12 } 13 } 14 15 // Expt set z to xᵗ (mod q¹²) and return z (t is the generator of the curve) 16 func (z *E12) Expt(x *E12) *E12 { 17 // Expt computation is derived from the addition chain: 18 // 19 // _10 = 2*1 20 // _100 = 2*_10 21 // _1000 = 2*_100 22 // _10000 = 2*_1000 23 // _10001 = 1 + _10000 24 // _10011 = _10 + _10001 25 // _10100 = 1 + _10011 26 // _11001 = _1000 + _10001 27 // _100010 = 2*_10001 28 // _100111 = _10011 + _10100 29 // _101001 = _10 + _100111 30 // i27 = (_100010 << 6 + _100 + _11001) << 7 + _11001 31 // i44 = (i27 << 8 + _101001 + _10) << 6 + _10001 32 // i70 = ((i44 << 8 + _101001) << 6 + _101001) << 10 33 // return (_100111 + i70) << 6 + _101001 + _1000 34 // 35 // Operations: 62 squares 17 multiplies 36 // 37 // Generated by github.com/mmcloughlin/addchain v0.4.0. 38 39 // Allocate Temporaries. 40 var result, t0, t1, t2, t3, t4, t5, t6 E12 41 42 // Step 1: t3 = x^0x2 43 t3.CyclotomicSquare(x) 44 45 // Step 2: t5 = x^0x4 46 t5.CyclotomicSquare(&t3) 47 48 // Step 3: result = x^0x8 49 result.CyclotomicSquare(&t5) 50 51 // Step 4: t0 = x^0x10 52 t0.CyclotomicSquare(&result) 53 54 // Step 5: t2 = x^0x11 55 t2.Mul(x, &t0) 56 57 // Step 6: t0 = x^0x13 58 t0.Mul(&t3, &t2) 59 60 // Step 7: t1 = x^0x14 61 t1.Mul(x, &t0) 62 63 // Step 8: t4 = x^0x19 64 t4.Mul(&result, &t2) 65 66 // Step 9: t6 = x^0x22 67 t6.CyclotomicSquare(&t2) 68 69 // Step 10: t1 = x^0x27 70 t1.Mul(&t0, &t1) 71 72 // Step 11: t0 = x^0x29 73 t0.Mul(&t3, &t1) 74 75 // Step 17: t6 = x^0x880 76 t6.nSquare(6) 77 78 // Step 18: t5 = x^0x884 79 t5.Mul(&t5, &t6) 80 81 // Step 19: t5 = x^0x89d 82 t5.Mul(&t4, &t5) 83 84 // Step 26: t5 = x^0x44e80 85 t5.nSquare(7) 86 87 // Step 27: t4 = x^0x44e99 88 t4.Mul(&t4, &t5) 89 90 // Step 35: t4 = x^0x44e9900 91 t4.nSquare(8) 92 93 // Step 36: t4 = x^0x44e9929 94 t4.Mul(&t0, &t4) 95 96 // Step 37: t3 = x^0x44e992b 97 t3.Mul(&t3, &t4) 98 99 // Step 43: t3 = x^0x113a64ac0 100 t3.nSquare(6) 101 102 // Step 44: t2 = x^0x113a64ad1 103 t2.Mul(&t2, &t3) 104 105 // Step 52: t2 = x^0x113a64ad100 106 t2.nSquare(8) 107 108 // Step 53: t2 = x^0x113a64ad129 109 t2.Mul(&t0, &t2) 110 111 // Step 59: t2 = x^0x44e992b44a40 112 t2.nSquare(6) 113 114 // Step 60: t2 = x^0x44e992b44a69 115 t2.Mul(&t0, &t2) 116 117 // Step 70: t2 = x^0x113a64ad129a400 118 t2.nSquare(10) 119 120 // Step 71: t1 = x^0x113a64ad129a427 121 t1.Mul(&t1, &t2) 122 123 // Step 77: t1 = x^0x44e992b44a6909c0 124 t1.nSquare(6) 125 126 // Step 78: t0 = x^0x44e992b44a6909e9 127 t0.Mul(&t0, &t1) 128 129 // Step 79: result = x^0x44e992b44a6909f1 130 z.Mul(&result, &t0) 131 132 return z 133 } 134 135 // MulBy034 multiplication by sparse element (c0,0,0,c3,c4,0) 136 func (z *E12) MulBy034(c0, c3, c4 *E2) *E12 { 137 138 var a, b, d E6 139 140 a.MulByE2(&z.C0, c0) 141 142 b.Set(&z.C1) 143 b.MulBy01(c3, c4) 144 145 var d0 E2 146 d0.Add(c0, c3) 147 d.Add(&z.C0, &z.C1) 148 d.MulBy01(&d0, c4) 149 150 z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d) 151 z.C0.MulByNonResidue(&b).Add(&z.C0, &a) 152 153 return z 154 } 155 156 // MulBy34 multiplication by sparse element (1,0,0,c3,c4,0) 157 func (z *E12) MulBy34(c3, c4 *E2) *E12 { 158 159 var a, b, d E6 160 161 a.Set(&z.C0) 162 163 b.Set(&z.C1) 164 b.MulBy01(c3, c4) 165 166 var d0 E2 167 d0.SetOne().Add(&d0, c3) 168 d.Add(&z.C0, &z.C1) 169 d.MulBy01(&d0, c4) 170 171 z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d) 172 z.C0.MulByNonResidue(&b).Add(&z.C0, &a) 173 174 return z 175 } 176 177 // Mul034By034 multiplication of sparse element (c0,0,0,c3,c4,0) by sparse element (d0,0,0,d3,d4,0) 178 func Mul034By034(d0, d3, d4, c0, c3, c4 *E2) [5]E2 { 179 var z00, tmp, x0, x3, x4, x04, x03, x34 E2 180 x0.Mul(c0, d0) 181 x3.Mul(c3, d3) 182 x4.Mul(c4, d4) 183 tmp.Add(c0, c4) 184 x04.Add(d0, d4). 185 Mul(&x04, &tmp). 186 Sub(&x04, &x0). 187 Sub(&x04, &x4) 188 tmp.Add(c0, c3) 189 x03.Add(d0, d3). 190 Mul(&x03, &tmp). 191 Sub(&x03, &x0). 192 Sub(&x03, &x3) 193 tmp.Add(c3, c4) 194 x34.Add(d3, d4). 195 Mul(&x34, &tmp). 196 Sub(&x34, &x3). 197 Sub(&x34, &x4) 198 199 z00.MulByNonResidue(&x4). 200 Add(&z00, &x0) 201 202 return [5]E2{z00, x3, x34, x03, x04} 203 } 204 205 // Mul34By34 multiplication of sparse element (1,0,0,c3,c4,0) by sparse element (1,0,0,d3,d4,0) 206 func Mul34By34(d3, d4, c3, c4 *E2) [5]E2 { 207 var z00, tmp, x0, x3, x4, x04, x03, x34 E2 208 x3.Mul(c3, d3) 209 x4.Mul(c4, d4) 210 x04.Add(c4, d4) 211 x03.Add(c3, d3) 212 tmp.Add(c3, c4) 213 x34.Add(d3, d4). 214 Mul(&x34, &tmp). 215 Sub(&x34, &x3). 216 Sub(&x34, &x4) 217 218 x0.SetOne() 219 z00.MulByNonResidue(&x4). 220 Add(&z00, &x0) 221 222 return [5]E2{z00, x3, x34, x03, x04} 223 } 224 225 // MulBy01234 multiplies z by an E12 sparse element of the form (x0, x1, x2, x3, x4, 0) 226 func (z *E12) MulBy01234(x *[5]E2) *E12 { 227 var c1, a, b, c, z0, z1 E6 228 c0 := &E6{B0: x[0], B1: x[1], B2: x[2]} 229 c1.B0 = x[3] 230 c1.B1 = x[4] 231 a.Add(&z.C0, &z.C1) 232 b.Add(c0, &c1) 233 a.Mul(&a, &b) 234 b.Mul(&z.C0, c0) 235 c.Set(&z.C1).MulBy01(&x[3], &x[4]) 236 z1.Sub(&a, &b) 237 z1.Sub(&z1, &c) 238 z0.MulByNonResidue(&c) 239 z0.Add(&z0, &b) 240 241 z.C0 = z0 242 z.C1 = z1 243 244 return z 245 }