github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/internal/fptower/e2_bls378.go (about) 1 // Copyright 2020 ConsenSys AG 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package fptower 16 17 import "github.com/consensys/gnark-crypto/ecc/bls12-378/fp" 18 19 // Mul sets z to the E2-product of x,y, returns z 20 func (z *E2) Mul(x, y *E2) *E2 { 21 var a, b, c fp.Element 22 a.Add(&x.A0, &x.A1) 23 b.Add(&y.A0, &y.A1) 24 a.Mul(&a, &b) 25 b.Mul(&x.A0, &y.A0) 26 c.Mul(&x.A1, &y.A1) 27 z.A1.Sub(&a, &b).Sub(&z.A1, &c) 28 fp.MulBy5(&c) 29 z.A0.Sub(&b, &c) 30 return z 31 } 32 33 // Square sets z to the E2-product of x,x returns z 34 func (z *E2) Square(x *E2) *E2 { 35 //algo 22 https://eprint.iacr.org/2010/354.pdf 36 var c0, c2 fp.Element 37 c0.Add(&x.A0, &x.A1) 38 c2.Neg(&x.A1) 39 fp.MulBy5(&c2) 40 c2.Add(&c2, &x.A0) 41 42 c0.Mul(&c0, &c2) // (x1+x2)*(x1+(u**2)x2) 43 c2.Mul(&x.A0, &x.A1).Double(&c2) 44 z.A1 = c2 45 c2.Double(&c2) 46 z.A0.Add(&c0, &c2) 47 48 return z 49 } 50 51 // MulByNonResidue multiplies a E2 by (0,1) 52 func (z *E2) MulByNonResidue(x *E2) *E2 { 53 a := x.A0 54 b := x.A1 // fetching x.A1 in the function below is slower 55 fp.MulBy5(&b) 56 z.A0.Neg(&b) 57 z.A1 = a 58 return z 59 } 60 61 // MulByNonResidueInv multiplies a E2 by (0,1)^{-1} 62 func (z *E2) MulByNonResidueInv(x *E2) *E2 { 63 //z.A1.MulByNonResidueInv(&x.A0) 64 a := x.A1 65 fiveinv := fp.Element{ 66 4714375566610504077, 67 585136512338283717, 68 16899133777167898908, 69 1882388787078723660, 70 12465292654455594957, 71 119042783712594200, 72 } 73 z.A1.Mul(&x.A0, &fiveinv).Neg(&z.A1) 74 z.A0 = a 75 return z 76 } 77 78 // Inverse sets z to the E2-inverse of x, returns z 79 func (z *E2) Inverse(x *E2) *E2 { 80 // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf 81 //var a, b, t0, t1, tmp fp.Element 82 var t0, t1, tmp fp.Element 83 a := &x.A0 // creating the buffers a, b is faster than querying &x.A0, &x.A1 in the functions call below 84 b := &x.A1 85 t0.Square(a) 86 t1.Square(b) 87 tmp.Set(&t1) 88 fp.MulBy5(&tmp) 89 t0.Add(&t0, &tmp) 90 t1.Inverse(&t0) 91 z.A0.Mul(a, &t1) 92 z.A1.Mul(b, &t1).Neg(&z.A1) 93 94 return z 95 } 96 97 // norm sets x to the norm of z 98 func (z *E2) norm(x *fp.Element) { 99 var tmp fp.Element 100 x.Square(&z.A1) 101 tmp.Set(x) 102 fp.MulBy5(&tmp) 103 x.Square(&z.A0).Add(x, &tmp) 104 }