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  }