github.com/cloudflare/circl@v1.5.0/ecc/bls12381/ff/fp4.go (about)

     1  package ff
     2  
     3  import "fmt"
     4  
     5  // Fp4Size is the size of an Fp4 element
     6  const Fp4Size = 4 * FpSize
     7  
     8  // Fp4 is obtained by adjoining t, the square root of u+1 to Fp2
     9  type Fp4 [2]Fp2
    10  
    11  func (z Fp4) String() string { return fmt.Sprintf("%s + ( %s )*t", z[0], z[1]) }
    12  
    13  func (z *Fp4) SetOne() {
    14  	z[0].SetOne()
    15  	z[1] = Fp2{}
    16  }
    17  
    18  func (z *Fp4) IsZero() int {
    19  	return z.IsEqual(&Fp4{})
    20  }
    21  
    22  func (z *Fp4) IsEqual(x *Fp4) int {
    23  	return z[0].IsEqual(&x[0]) & z[1].IsEqual(&x[1])
    24  }
    25  
    26  func (z *Fp4) Cjg() { z[1].Neg() }
    27  
    28  func (z *Fp4) Neg() {
    29  	z[0].Neg()
    30  	z[1].Neg()
    31  }
    32  
    33  func (z *Fp4) Add(x *Fp4, y *Fp4) {
    34  	z[0].Add(&x[0], &y[0])
    35  	z[1].Add(&x[1], &y[1])
    36  }
    37  
    38  func (z *Fp4) Sub(x *Fp4, y *Fp4) {
    39  	z[0].Sub(&x[0], &y[0])
    40  	z[1].Sub(&x[1], &y[1])
    41  }
    42  
    43  func (z *Fp4) Mul(x *Fp4, y *Fp4) {
    44  	var x0y0, x1y1, sx, sy, k Fp2
    45  	x0y0.Mul(&x[0], &y[0])
    46  	x1y1.Mul(&x[1], &y[1])
    47  	sx.Add(&x[0], &x[1])
    48  	sy.Add(&y[0], &y[1])
    49  	k.Mul(&sx, &sy)
    50  	k.Sub(&k, &x0y0)
    51  	k.Sub(&k, &x1y1)
    52  	// k is x0y1+x1y0 computed as (x0+x1)(y0+y1)-x0y0-x1y1
    53  	z[1] = k
    54  	// Multiply x1y1 by u+1
    55  	z[0][1].Add(&x1y1[0], &x1y1[1])
    56  	z[0][0].Sub(&x1y1[0], &x1y1[1])
    57  	z[0].Add(&z[0], &x0y0)
    58  }
    59  
    60  func (z *Fp4) Sqr(x *Fp4) {
    61  	var x0s, x1s, sx, k Fp2
    62  	x0s.Sqr(&x[0])
    63  	x1s.Sqr(&x[1])
    64  	sx.Add(&x[0], &x[1])
    65  	k.Sqr(&sx)
    66  	k.Sub(&k, &x0s)
    67  	k.Sub(&k, &x1s)
    68  
    69  	z[1] = k
    70  	// Multiplying x1s by u+1
    71  	z[0][1].Add(&x1s[0], &x1s[1])
    72  	z[0][0].Sub(&x1s[0], &x1s[1])
    73  	z[0].Add(&z[0], &x0s)
    74  }
    75  
    76  func (z *Fp4) Inv(x *Fp4) {
    77  	// Compute the inverse via conjugation
    78  	var denom, x0sqr, x1sqr Fp2
    79  	x0sqr.Sqr(&x[0])
    80  	x1sqr.Sqr(&x[1])
    81  	denom[1].Add(&x1sqr[0], &x1sqr[1])
    82  	denom[0].Sub(&x1sqr[0], &x1sqr[1])
    83  	denom.Sub(&x0sqr, &denom)
    84  	denom.Inv(&denom)
    85  	z[0] = x[0]
    86  	z[1].Sub(&z[1], &x[1])
    87  	z.mulSubfield(z, &denom)
    88  }
    89  
    90  func (z *Fp4) mulSubfield(x *Fp4, y *Fp2) {
    91  	z[0].Mul(&x[0], y)
    92  	z[1].Mul(&x[1], y)
    93  }
    94  
    95  func (z *Fp4) mulT(x *Fp4) {
    96  	var t Fp4
    97  	t[1] = x[0]
    98  	t[0][1].Add(&x[1][0], &x[1][1])
    99  	t[0][0].Sub(&x[1][0], &x[1][1])
   100  	*z = t
   101  }