github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/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  // Expt set z to x^t in E12 and return z
    16  func (z *E12) Expt(x *E12) *E12 {
    17  
    18  	// Expt computation is derived from the addition chain:
    19  	//
    20  	//	_1000     = 1 << 3
    21  	//	_1001     = 1 + _1000
    22  	//	_1001000  = _1001 << 3
    23  	//	_1010001  = _1001 + _1001000
    24  	//	_10011001 = _1001000 + _1010001
    25  	//	i67       = ((_10011001 << 5 + _1001) << 10 + _1010001) << 41
    26  	//	return      1 + i67
    27  	//
    28  	// Operations: 62 squares 6 multiplies
    29  	//
    30  	// Generated by github.com/mmcloughlin/addchain v0.4.0.
    31  
    32  	// Allocate Temporaries.
    33  	var result, t0, t1 E12
    34  
    35  	// Step 3: result = x^0x8
    36  	result.CyclotomicSquare(x)
    37  	result.nSquare(2)
    38  
    39  	// Step 4: t0 = x^0x9
    40  	t0.Mul(x, &result)
    41  
    42  	// Step 7: t1 = x^0x48
    43  	t1.CyclotomicSquare(&t0)
    44  	t1.nSquare(2)
    45  
    46  	// Step 8: result = x^0x51
    47  	result.Mul(&t0, &t1)
    48  
    49  	// Step 9: t1 = x^0x99
    50  	t1.Mul(&t1, &result)
    51  
    52  	// Step 14: t1 = x^0x1320
    53  	t1.nSquare(5)
    54  
    55  	// Step 15: t0 = x^0x1329
    56  	t0.Mul(&t0, &t1)
    57  
    58  	// Step 25: t0 = x^0x4ca400
    59  	t0.nSquare(10)
    60  
    61  	// Step 26: result = x^0x4ca451
    62  	result.Mul(&result, &t0)
    63  
    64  	// Step 67: result = x^0x9948a20000000000
    65  	result.nSquareCompressed(41)
    66  	result.DecompressKarabina(&result)
    67  
    68  	// Step 68: result = x^0x9948a20000000001
    69  	z.Mul(x, &result)
    70  
    71  	return z
    72  }
    73  
    74  // MulBy014 multiplication by sparse element (c0, c1, 0, 0, c4)
    75  func (z *E12) MulBy014(c0, c1, c4 *E2) *E12 {
    76  
    77  	var a, b E6
    78  	var d E2
    79  
    80  	a.Set(&z.C0)
    81  	a.MulBy01(c0, c1)
    82  
    83  	b.Set(&z.C1)
    84  	b.MulBy1(c4)
    85  	d.Add(c1, c4)
    86  
    87  	z.C1.Add(&z.C1, &z.C0)
    88  	z.C1.MulBy01(c0, &d)
    89  	z.C1.Sub(&z.C1, &a)
    90  	z.C1.Sub(&z.C1, &b)
    91  	z.C0.MulByNonResidue(&b)
    92  	z.C0.Add(&z.C0, &a)
    93  
    94  	return z
    95  }
    96  
    97  // MulBy01 multiplication by sparse element (c0, c1, 0, 0, 1)
    98  func (z *E12) MulBy01(c0, c1 *E2) *E12 {
    99  
   100  	var a, b E6
   101  	var d E2
   102  
   103  	a.Set(&z.C0)
   104  	a.MulBy01(c0, c1)
   105  
   106  	b.MulByNonResidue(&z.C1)
   107  	d.SetOne().Add(c1, &d)
   108  
   109  	z.C1.Add(&z.C1, &z.C0)
   110  	z.C1.MulBy01(c0, &d)
   111  	z.C1.Sub(&z.C1, &a)
   112  	z.C1.Sub(&z.C1, &b)
   113  	z.C0.MulByNonResidue(&b)
   114  	z.C0.Add(&z.C0, &a)
   115  
   116  	return z
   117  }
   118  
   119  // Mul014By014 multiplication of sparse element (c0,c1,0,0,c4,0) by sparse element (d0,d1,0,0,d4,0)
   120  func Mul014By014(d0, d1, d4, c0, c1, c4 *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.Mul(c4, d4)
   125  	tmp.Add(c0, c4)
   126  	x04.Add(d0, d4).
   127  		Mul(&x04, &tmp).
   128  		Sub(&x04, &x0).
   129  		Sub(&x04, &x4)
   130  	tmp.Add(c0, c1)
   131  	x01.Add(d0, d1).
   132  		Mul(&x01, &tmp).
   133  		Sub(&x01, &x0).
   134  		Sub(&x01, &x1)
   135  	tmp.Add(c1, c4)
   136  	x14.Add(d1, d4).
   137  		Mul(&x14, &tmp).
   138  		Sub(&x14, &x1).
   139  		Sub(&x14, &x4)
   140  
   141  	z00.MulByNonResidue(&x4).
   142  		Add(&z00, &x0)
   143  
   144  	return [5]E2{z00, x01, x1, x04, x14}
   145  }
   146  
   147  // Mul01By01 multiplication of sparse element (c0,c1,0,0,1,0) by sparse element (d0,d1,0,0,1,0)
   148  func Mul01By01(d0, d1, c0, c1 *E2) [5]E2 {
   149  	var z00, tmp, x0, x1, x4, x04, x01, x14 E2
   150  	x0.Mul(c0, d0)
   151  	x1.Mul(c1, d1)
   152  	x4.SetOne()
   153  	x04.Add(d0, c0)
   154  	tmp.Add(c0, c1)
   155  	x01.Add(d0, d1).
   156  		Mul(&x01, &tmp).
   157  		Sub(&x01, &x0).
   158  		Sub(&x01, &x1)
   159  	x14.Add(d1, c1)
   160  
   161  	z00.MulByNonResidue(&x4).
   162  		Add(&z00, &x0)
   163  
   164  	return [5]E2{z00, x01, x1, x04, x14}
   165  }
   166  
   167  // MulBy01245 multiplies z by an E12 sparse element of the form (x0, x1, x2, 0, x4, x5)
   168  func (z *E12) MulBy01245(x *[5]E2) *E12 {
   169  	var c1, a, b, c, z0, z1 E6
   170  	c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
   171  	c1.B1 = x[3]
   172  	c1.B2 = x[4]
   173  	a.Add(&z.C0, &z.C1)
   174  	b.Add(c0, &c1)
   175  	a.Mul(&a, &b)
   176  	b.Mul(&z.C0, c0)
   177  	c.Set(&z.C1).MulBy12(&x[3], &x[4])
   178  	z1.Sub(&a, &b)
   179  	z1.Sub(&z1, &c)
   180  	z0.MulByNonResidue(&c)
   181  	z0.Add(&z0, &b)
   182  
   183  	z.C0 = z0
   184  	z.C1 = z1
   185  
   186  	return z
   187  }