github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/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^t in E12 and return z 16 func (z *E12) Expt(x *E12) *E12 { 17 // const tAbsVal uint64 = 9586122913090633729 18 // tAbsVal in binary: 1000010100001000110000000000000000000000000000000000000000000001 19 // drop the low 46 bits (all 0 except the least significant bit): 100001010000100011 = 136227 20 // Shortest addition chains can be found at https://wwwhomes.uni-bielefeld.de/achim/addition_chain.html 21 22 var result, x33 E12 23 24 // a shortest addition chain for 136227 25 result.Set(x) 26 result.nSquare(5) 27 result.Mul(&result, x) 28 x33.Set(&result) 29 result.nSquare(7) 30 result.Mul(&result, &x33) 31 result.nSquare(4) 32 result.Mul(&result, x) 33 result.CyclotomicSquare(&result) 34 result.Mul(&result, x) 35 36 // the remaining 46 bits 37 result.nSquareCompressed(46) 38 result.DecompressKarabina(&result) 39 result.Mul(&result, x) 40 41 z.Set(&result) 42 return z 43 } 44 45 // MulBy034 multiplication by sparse element (c0,0,0,c3,c4,0) 46 func (z *E12) MulBy034(c0, c3, c4 *E2) *E12 { 47 48 var a, b, d E6 49 50 a.MulByE2(&z.C0, c0) 51 52 b.Set(&z.C1) 53 b.MulBy01(c3, c4) 54 55 var d0 E2 56 d0.Add(c0, c3) 57 d.Add(&z.C0, &z.C1) 58 d.MulBy01(&d0, c4) 59 60 z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d) 61 z.C0.MulByNonResidue(&b).Add(&z.C0, &a) 62 63 return z 64 } 65 66 // MulBy34 multiplication by sparse element (1,0,0,c3,c4,0) 67 func (z *E12) MulBy34(c3, c4 *E2) *E12 { 68 69 var a, b, d E6 70 71 a.Set(&z.C0) 72 73 b.Set(&z.C1) 74 b.MulBy01(c3, c4) 75 76 var d0 E2 77 d0.SetOne().Add(&d0, c3) 78 d.Add(&z.C0, &z.C1) 79 d.MulBy01(&d0, c4) 80 81 z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d) 82 z.C0.MulByNonResidue(&b).Add(&z.C0, &a) 83 84 return z 85 } 86 87 // Mul034By034 multiplication of sparse element (c0,0,0,c3,c4,0) by sparse element (d0,0,0,d3,d4,0) 88 func Mul034By034(d0, d3, d4, c0, c3, c4 *E2) [5]E2 { 89 var z00, tmp, x0, x3, x4, x04, x03, x34 E2 90 x0.Mul(c0, d0) 91 x3.Mul(c3, d3) 92 x4.Mul(c4, d4) 93 tmp.Add(c0, c4) 94 x04.Add(d0, d4). 95 Mul(&x04, &tmp). 96 Sub(&x04, &x0). 97 Sub(&x04, &x4) 98 tmp.Add(c0, c3) 99 x03.Add(d0, d3). 100 Mul(&x03, &tmp). 101 Sub(&x03, &x0). 102 Sub(&x03, &x3) 103 tmp.Add(c3, c4) 104 x34.Add(d3, d4). 105 Mul(&x34, &tmp). 106 Sub(&x34, &x3). 107 Sub(&x34, &x4) 108 109 z00.MulByNonResidue(&x4). 110 Add(&z00, &x0) 111 112 return [5]E2{z00, x3, x34, x03, x04} 113 } 114 115 // Mul34By34 multiplication of sparse element (1,0,0,c3,c4,0) by sparse element (1,0,0,d3,d4,0) 116 func Mul34By34(d3, d4, c3, c4 *E2) [5]E2 { 117 var z00, tmp, x0, x3, x4, x04, x03, x34 E2 118 x3.Mul(c3, d3) 119 x4.Mul(c4, d4) 120 x04.Add(c4, d4) 121 x03.Add(c3, d3) 122 tmp.Add(c3, c4) 123 x34.Add(d3, d4). 124 Mul(&x34, &tmp). 125 Sub(&x34, &x3). 126 Sub(&x34, &x4) 127 128 x0.SetOne() 129 z00.MulByNonResidue(&x4). 130 Add(&z00, &x0) 131 132 return [5]E2{z00, x3, x34, x03, x04} 133 } 134 135 // MulBy01234 multiplies z by an E12 sparse element of the form (x0, x1, x2, x3, x4, 0) 136 func (z *E12) MulBy01234(x *[5]E2) *E12 { 137 var c1, a, b, c, z0, z1 E6 138 c0 := &E6{B0: x[0], B1: x[1], B2: x[2]} 139 c1.B0 = x[3] 140 c1.B1 = x[4] 141 a.Add(&z.C0, &z.C1) 142 b.Add(c0, &c1) 143 a.Mul(&a, &b) 144 b.Mul(&z.C0, c0) 145 c.Set(&z.C1).MulBy01(&x[3], &x[4]) 146 z1.Sub(&a, &b) 147 z1.Sub(&z1, &c) 148 z0.MulByNonResidue(&c) 149 z0.Add(&z0, &b) 150 151 z.C0 = z0 152 z.C1 = z1 153 154 return z 155 }