github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-315/internal/fptower/e2_bls315.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/bls24-315/fp"
    19  )
    20  
    21  // used with !amd64, make staticcheck happier.
    22  var (
    23  	_ = mulGenericE2
    24  )
    25  
    26  func mulGenericE2(z, x, y *E2) {
    27  	var a, b, c fp.Element
    28  	a.Add(&x.A0, &x.A1)
    29  	b.Add(&y.A0, &y.A1)
    30  	a.Mul(&a, &b)
    31  	b.Mul(&x.A0, &y.A0)
    32  	c.Mul(&x.A1, &y.A1)
    33  	z.A1.Sub(&a, &b).Sub(&z.A1, &c)
    34  	fp.MulBy13(&c)
    35  	z.A0.Add(&c, &b)
    36  }
    37  
    38  // Square sets z to the E2-product of x,x returns z
    39  func (z *E2) Square(x *E2) *E2 {
    40  	//algo 22 https://eprint.iacr.org/2010/354.pdf
    41  	var c0, c2 fp.Element
    42  	c0 = x.A1
    43  	fp.MulBy13(&c0)
    44  	c2.Add(&c0, &x.A0)
    45  	c0.Add(&x.A0, &x.A1)
    46  	c0.Mul(&c0, &c2) // (x1+x2)*(x1+(u**2)x2)
    47  	z.A1.Mul(&x.A0, &x.A1).Double(&z.A1)
    48  	c2.Double(&z.A1).Double(&c2).Double(&c2) // 8 z.A1
    49  	z.A0.Sub(&c0, &c2).Add(&z.A0, &z.A1)
    50  
    51  	return z
    52  }
    53  
    54  // MulByNonResidueInv multiplies a E2 by (0,1)^{-1}
    55  func (z *E2) MulByNonResidueInv(x *E2) *E2 {
    56  	a := x.A1
    57  	thirteeninv := fp.Element{
    58  		14835018474091022805,
    59  		4059211274438447823,
    60  		17174191230683291349,
    61  		5795645494093750226,
    62  		179263826259076473,
    63  	}
    64  	z.A1.Mul(&x.A0, &thirteeninv)
    65  	z.A0 = a
    66  	return z
    67  }
    68  
    69  // Inverse sets z to the E2-inverse of x, returns z
    70  //
    71  // if x == 0, sets and returns z = x
    72  func (z *E2) Inverse(x *E2) *E2 {
    73  	// Algorithm 8 from https://eprint.iacr.org/2010/354.pdf
    74  	//var a, b, t0, t1, tmp fp.Element
    75  	var t0, t1 fp.Element
    76  	a := &x.A0 // creating the buffers a, b is faster than querying &x.A0, &x.A1 in the functions call below
    77  	b := &x.A1
    78  	t0.Square(a)
    79  	t1.Square(b)
    80  	fp.MulBy13(&t1)
    81  	t0.Sub(&t0, &t1)
    82  	t1.Inverse(&t0)
    83  	z.A0.Mul(a, &t1)
    84  	z.A1.Mul(b, &t1).Neg(&z.A1)
    85  
    86  	return z
    87  }
    88  
    89  // norm sets x to the norm of z
    90  func (z *E2) norm(x *fp.Element) {
    91  	var tmp0, tmp1 fp.Element
    92  	x.Square(&z.A1)
    93  	tmp0.Double(x).Double(&tmp0)
    94  	tmp1.Double(&tmp0).Add(&tmp1, &tmp0).Add(&tmp1, x)
    95  	x.Square(&z.A0).Sub(x, &tmp1)
    96  }