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  }