github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/internal/fptower/e2_bls377.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 ( 18 "github.com/consensys/gnark-crypto/ecc/bls12-377/fp" 19 ) 20 21 // Mul sets z to the E2-product of x,y, returns z 22 func (z *E2) Mul(x, y *E2) *E2 { 23 var a, b, c fp.Element 24 a.Add(&x.A0, &x.A1) 25 b.Add(&y.A0, &y.A1) 26 a.Mul(&a, &b) 27 b.Mul(&x.A0, &y.A0) 28 c.Mul(&x.A1, &y.A1) 29 z.A1.Sub(&a, &b).Sub(&z.A1, &c) 30 fp.MulBy5(&c) 31 z.A0.Sub(&b, &c) 32 return z 33 } 34 35 // Square sets z to the E2-product of x,x returns z 36 func (z *E2) Square(x *E2) *E2 { 37 //algo 22 https://eprint.iacr.org/2010/354.pdf 38 var c0, c2 fp.Element 39 c0.Add(&x.A0, &x.A1) 40 c2.Neg(&x.A1) 41 fp.MulBy5(&c2) 42 c2.Add(&c2, &x.A0) 43 44 c0.Mul(&c0, &c2) // (x1+x2)*(x1+(u**2)x2) 45 c2.Mul(&x.A0, &x.A1).Double(&c2) 46 z.A1 = c2 47 c2.Double(&c2) 48 z.A0.Add(&c0, &c2) 49 50 return z 51 } 52 53 // MulByNonResidue multiplies a E2 by (0,1) 54 func (z *E2) MulByNonResidue(x *E2) *E2 { 55 a := x.A0 56 b := x.A1 // fetching x.A1 in the function below is slower 57 fp.MulBy5(&b) 58 z.A0.Neg(&b) 59 z.A1 = a 60 return z 61 } 62 63 // MulByNonResidueInv multiplies a E2 by (0,1)^{-1} 64 func (z *E2) MulByNonResidueInv(x *E2) *E2 { 65 //z.A1.MulByNonResidueInv(&x.A0) 66 a := x.A1 67 fiveinv := fp.Element{ 68 330620507644336508, 69 9878087358076053079, 70 11461392860540703536, 71 6973035786057818995, 72 8846909097162646007, 73 104838758629667239, 74 } 75 z.A1.Mul(&x.A0, &fiveinv).Neg(&z.A1) 76 z.A0 = a 77 return z 78 } 79 80 // Inverse sets z to the E2-inverse of x, returns z 81 func (z *E2) Inverse(x *E2) *E2 { 82 // Algorithm 8 from https://eprint.iacr.org/2010/354.pdf 83 //var a, b, t0, t1, tmp fp.Element 84 var t0, t1, tmp fp.Element 85 a := &x.A0 // creating the buffers a, b is faster than querying &x.A0, &x.A1 in the functions call below 86 b := &x.A1 87 t0.Square(a) 88 t1.Square(b) 89 tmp.Set(&t1) 90 fp.MulBy5(&tmp) 91 t0.Add(&t0, &tmp) 92 t1.Inverse(&t0) 93 z.A0.Mul(a, &t1) 94 z.A1.Mul(b, &t1).Neg(&z.A1) 95 96 return z 97 } 98 99 // norm sets x to the norm of z 100 func (z *E2) norm(x *fp.Element) { 101 var tmp fp.Element 102 x.Square(&z.A1) 103 tmp.Set(x) 104 fp.MulBy5(&tmp) 105 x.Square(&z.A0).Add(x, &tmp) 106 } 107 108 // MulBybTwistCurveCoeff multiplies by 1/(0,1) 109 func (z *E2) MulBybTwistCurveCoeff(x *E2) *E2 { 110 111 var res E2 112 res.A0.Set(&x.A1) 113 res.A1.MulByNonResidueInv(&x.A0) 114 z.Set(&res) 115 116 return z 117 }