github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/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 // ExptHalf set z to x^(t/2) in E12 and return z 16 // const t/2 uint64 = 7566188111470821376 // negative 17 func (z *E12) ExptHalf(x *E12) *E12 { 18 var result E12 19 var t [2]E12 20 result.Set(x) 21 result.nSquareCompressed(15) 22 t[0].Set(&result) 23 result.nSquareCompressed(32) 24 t[1].Set(&result) 25 batch := BatchDecompressKarabina([]E12{t[0], t[1]}) 26 result.Mul(&batch[0], &batch[1]) 27 batch[1].nSquare(9) 28 result.Mul(&result, &batch[1]) 29 batch[1].nSquare(3) 30 result.Mul(&result, &batch[1]) 31 batch[1].nSquare(2) 32 result.Mul(&result, &batch[1]) 33 batch[1].CyclotomicSquare(&batch[1]) 34 result.Mul(&result, &batch[1]) 35 return z.Conjugate(&result) // because tAbsVal is negative 36 } 37 38 // Expt set z to xᵗ in E12 and return z 39 // const t uint64 = 15132376222941642752 // negative 40 func (z *E12) Expt(x *E12) *E12 { 41 var result E12 42 result.ExptHalf(x) 43 return z.CyclotomicSquare(&result) 44 } 45 46 // MulBy014 multiplication by sparse element (c0, c1, 0, 0, c4) 47 func (z *E12) MulBy014(c0, c1, c4 *E2) *E12 { 48 49 var a, b E6 50 var d E2 51 52 a.Set(&z.C0) 53 a.MulBy01(c0, c1) 54 55 b.Set(&z.C1) 56 b.MulBy1(c4) 57 d.Add(c1, c4) 58 59 z.C1.Add(&z.C1, &z.C0) 60 z.C1.MulBy01(c0, &d) 61 z.C1.Sub(&z.C1, &a) 62 z.C1.Sub(&z.C1, &b) 63 z.C0.MulByNonResidue(&b) 64 z.C0.Add(&z.C0, &a) 65 66 return z 67 } 68 69 // MulBy01 multiplication by sparse element (c0, c1, 0, 0, 1) 70 func (z *E12) MulBy01(c0, c1 *E2) *E12 { 71 72 var a, b E6 73 var d E2 74 75 a.Set(&z.C0) 76 a.MulBy01(c0, c1) 77 78 b.MulByNonResidue(&z.C1) 79 d.SetOne().Add(c1, &d) 80 81 z.C1.Add(&z.C1, &z.C0) 82 z.C1.MulBy01(c0, &d) 83 z.C1.Sub(&z.C1, &a) 84 z.C1.Sub(&z.C1, &b) 85 z.C0.MulByNonResidue(&b) 86 z.C0.Add(&z.C0, &a) 87 88 return z 89 } 90 91 // Mul014By014 multiplication of sparse element (c0,c1,0,0,c4,0) by sparse element (d0,d1,0,0,d4,0) 92 func Mul014By014(d0, d1, d4, c0, c1, c4 *E2) [5]E2 { 93 var z00, tmp, x0, x1, x4, x04, x01, x14 E2 94 x0.Mul(c0, d0) 95 x1.Mul(c1, d1) 96 x4.Mul(c4, d4) 97 tmp.Add(c0, c4) 98 x04.Add(d0, d4). 99 Mul(&x04, &tmp). 100 Sub(&x04, &x0). 101 Sub(&x04, &x4) 102 tmp.Add(c0, c1) 103 x01.Add(d0, d1). 104 Mul(&x01, &tmp). 105 Sub(&x01, &x0). 106 Sub(&x01, &x1) 107 tmp.Add(c1, c4) 108 x14.Add(d1, d4). 109 Mul(&x14, &tmp). 110 Sub(&x14, &x1). 111 Sub(&x14, &x4) 112 113 z00.MulByNonResidue(&x4). 114 Add(&z00, &x0) 115 116 return [5]E2{z00, x01, x1, x04, x14} 117 } 118 119 // Mul01By01 multiplication of sparse element (c0,c1,0,0,1,0) by sparse element (d0,d1,0,0,1,0) 120 func Mul01By01(d0, d1, c0, c1 *E2) [5]E2 { 121 var z00, tmp, x0, x1, x4, x04, x01, x14 E2 122 x0.Mul(c0, d0) 123 x1.Mul(c1, d1) 124 x4.SetOne() 125 x04.Add(d0, c0) 126 tmp.Add(c0, c1) 127 x01.Add(d0, d1). 128 Mul(&x01, &tmp). 129 Sub(&x01, &x0). 130 Sub(&x01, &x1) 131 x14.Add(d1, c1) 132 133 z00.MulByNonResidue(&x4). 134 Add(&z00, &x0) 135 136 return [5]E2{z00, x01, x1, x04, x14} 137 } 138 139 // MulBy01245 multiplies z by an E12 sparse element of the form (x0, x1, x2, 0, x4, x5) 140 func (z *E12) MulBy01245(x *[5]E2) *E12 { 141 var c1, a, b, c, z0, z1 E6 142 c0 := &E6{B0: x[0], B1: x[1], B2: x[2]} 143 c1.B1 = x[3] 144 c1.B2 = x[4] 145 a.Add(&z.C0, &z.C1) 146 b.Add(c0, &c1) 147 a.Mul(&a, &b) 148 b.Mul(&z.C0, c0) 149 c.Set(&z.C1).MulBy12(&x[3], &x[4]) 150 z1.Sub(&a, &b) 151 z1.Sub(&z1, &c) 152 z0.MulByNonResidue(&c) 153 z0.Add(&z0, &b) 154 155 z.C0 = z0 156 z.C1 = z1 157 158 return z 159 }