github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/internal/fptower/e12_pairing.go (about)

     1  package fptower
     2  
     3  func (z *E12) nSquare(n int) {
     4  	for i := 0; i < n; i++ {
     5  		z.CyclotomicSquare(z)
     6  	}
     7  }
     8  
     9  func (z *E12) nSquareCompressed(n int) {
    10  	for i := 0; i < n; i++ {
    11  		z.CyclotomicSquareCompressed(z)
    12  	}
    13  }
    14  
    15  // ExptHalf set z to x^(t/2) in E12 and return z
    16  // const t/2 uint64 = 7566188111470821376 // negative
    17  func (z *E12) ExptHalf(x *E12) *E12 {
    18  	var result E12
    19  	var t [2]E12
    20  	result.Set(x)
    21  	result.nSquareCompressed(15)
    22  	t[0].Set(&result)
    23  	result.nSquareCompressed(32)
    24  	t[1].Set(&result)
    25  	batch := BatchDecompressKarabina([]E12{t[0], t[1]})
    26  	result.Mul(&batch[0], &batch[1])
    27  	batch[1].nSquare(9)
    28  	result.Mul(&result, &batch[1])
    29  	batch[1].nSquare(3)
    30  	result.Mul(&result, &batch[1])
    31  	batch[1].nSquare(2)
    32  	result.Mul(&result, &batch[1])
    33  	batch[1].CyclotomicSquare(&batch[1])
    34  	result.Mul(&result, &batch[1])
    35  	return z.Conjugate(&result) // because tAbsVal is negative
    36  }
    37  
    38  // Expt set z to xᵗ in E12 and return z
    39  // const t uint64 = 15132376222941642752 // negative
    40  func (z *E12) Expt(x *E12) *E12 {
    41  	var result E12
    42  	result.ExptHalf(x)
    43  	return z.CyclotomicSquare(&result)
    44  }
    45  
    46  // MulBy014 multiplication by sparse element (c0, c1, 0, 0, c4)
    47  func (z *E12) MulBy014(c0, c1, c4 *E2) *E12 {
    48  
    49  	var a, b E6
    50  	var d E2
    51  
    52  	a.Set(&z.C0)
    53  	a.MulBy01(c0, c1)
    54  
    55  	b.Set(&z.C1)
    56  	b.MulBy1(c4)
    57  	d.Add(c1, c4)
    58  
    59  	z.C1.Add(&z.C1, &z.C0)
    60  	z.C1.MulBy01(c0, &d)
    61  	z.C1.Sub(&z.C1, &a)
    62  	z.C1.Sub(&z.C1, &b)
    63  	z.C0.MulByNonResidue(&b)
    64  	z.C0.Add(&z.C0, &a)
    65  
    66  	return z
    67  }
    68  
    69  // MulBy01 multiplication by sparse element (c0, c1, 0, 0, 1)
    70  func (z *E12) MulBy01(c0, c1 *E2) *E12 {
    71  
    72  	var a, b E6
    73  	var d E2
    74  
    75  	a.Set(&z.C0)
    76  	a.MulBy01(c0, c1)
    77  
    78  	b.MulByNonResidue(&z.C1)
    79  	d.SetOne().Add(c1, &d)
    80  
    81  	z.C1.Add(&z.C1, &z.C0)
    82  	z.C1.MulBy01(c0, &d)
    83  	z.C1.Sub(&z.C1, &a)
    84  	z.C1.Sub(&z.C1, &b)
    85  	z.C0.MulByNonResidue(&b)
    86  	z.C0.Add(&z.C0, &a)
    87  
    88  	return z
    89  }
    90  
    91  // Mul014By014 multiplication of sparse element (c0,c1,0,0,c4,0) by sparse element (d0,d1,0,0,d4,0)
    92  func Mul014By014(d0, d1, d4, c0, c1, c4 *E2) [5]E2 {
    93  	var z00, tmp, x0, x1, x4, x04, x01, x14 E2
    94  	x0.Mul(c0, d0)
    95  	x1.Mul(c1, d1)
    96  	x4.Mul(c4, d4)
    97  	tmp.Add(c0, c4)
    98  	x04.Add(d0, d4).
    99  		Mul(&x04, &tmp).
   100  		Sub(&x04, &x0).
   101  		Sub(&x04, &x4)
   102  	tmp.Add(c0, c1)
   103  	x01.Add(d0, d1).
   104  		Mul(&x01, &tmp).
   105  		Sub(&x01, &x0).
   106  		Sub(&x01, &x1)
   107  	tmp.Add(c1, c4)
   108  	x14.Add(d1, d4).
   109  		Mul(&x14, &tmp).
   110  		Sub(&x14, &x1).
   111  		Sub(&x14, &x4)
   112  
   113  	z00.MulByNonResidue(&x4).
   114  		Add(&z00, &x0)
   115  
   116  	return [5]E2{z00, x01, x1, x04, x14}
   117  }
   118  
   119  // Mul01By01 multiplication of sparse element (c0,c1,0,0,1,0) by sparse element (d0,d1,0,0,1,0)
   120  func Mul01By01(d0, d1, c0, c1 *E2) [5]E2 {
   121  	var z00, tmp, x0, x1, x4, x04, x01, x14 E2
   122  	x0.Mul(c0, d0)
   123  	x1.Mul(c1, d1)
   124  	x4.SetOne()
   125  	x04.Add(d0, c0)
   126  	tmp.Add(c0, c1)
   127  	x01.Add(d0, d1).
   128  		Mul(&x01, &tmp).
   129  		Sub(&x01, &x0).
   130  		Sub(&x01, &x1)
   131  	x14.Add(d1, c1)
   132  
   133  	z00.MulByNonResidue(&x4).
   134  		Add(&z00, &x0)
   135  
   136  	return [5]E2{z00, x01, x1, x04, x14}
   137  }
   138  
   139  // MulBy01245 multiplies z by an E12 sparse element of the form (x0, x1, x2, 0, x4, x5)
   140  func (z *E12) MulBy01245(x *[5]E2) *E12 {
   141  	var c1, a, b, c, z0, z1 E6
   142  	c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
   143  	c1.B1 = x[3]
   144  	c1.B2 = x[4]
   145  	a.Add(&z.C0, &z.C1)
   146  	b.Add(c0, &c1)
   147  	a.Mul(&a, &b)
   148  	b.Mul(&z.C0, c0)
   149  	c.Set(&z.C1).MulBy12(&x[3], &x[4])
   150  	z1.Sub(&a, &b)
   151  	z1.Sub(&z1, &c)
   152  	z0.MulByNonResidue(&c)
   153  	z0.Add(&z0, &b)
   154  
   155  	z.C0 = z0
   156  	z.C1 = z1
   157  
   158  	return z
   159  }