github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/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ᵗ (mod q¹²) and return z (t is the generator of the curve)
    16  func (z *E12) Expt(x *E12) *E12 {
    17  	// Expt computation is derived from the addition chain:
    18  	//
    19  	//	_10     = 2*1
    20  	//	_100    = 2*_10
    21  	//	_1000   = 2*_100
    22  	//	_10000  = 2*_1000
    23  	//	_10001  = 1 + _10000
    24  	//	_10011  = _10 + _10001
    25  	//	_10100  = 1 + _10011
    26  	//	_11001  = _1000 + _10001
    27  	//	_100010 = 2*_10001
    28  	//	_100111 = _10011 + _10100
    29  	//	_101001 = _10 + _100111
    30  	//	i27     = (_100010 << 6 + _100 + _11001) << 7 + _11001
    31  	//	i44     = (i27 << 8 + _101001 + _10) << 6 + _10001
    32  	//	i70     = ((i44 << 8 + _101001) << 6 + _101001) << 10
    33  	//	return    (_100111 + i70) << 6 + _101001 + _1000
    34  	//
    35  	// Operations: 62 squares 17 multiplies
    36  	//
    37  	// Generated by github.com/mmcloughlin/addchain v0.4.0.
    38  
    39  	// Allocate Temporaries.
    40  	var result, t0, t1, t2, t3, t4, t5, t6 E12
    41  
    42  	// Step 1: t3 = x^0x2
    43  	t3.CyclotomicSquare(x)
    44  
    45  	// Step 2: t5 = x^0x4
    46  	t5.CyclotomicSquare(&t3)
    47  
    48  	// Step 3: result = x^0x8
    49  	result.CyclotomicSquare(&t5)
    50  
    51  	// Step 4: t0 = x^0x10
    52  	t0.CyclotomicSquare(&result)
    53  
    54  	// Step 5: t2 = x^0x11
    55  	t2.Mul(x, &t0)
    56  
    57  	// Step 6: t0 = x^0x13
    58  	t0.Mul(&t3, &t2)
    59  
    60  	// Step 7: t1 = x^0x14
    61  	t1.Mul(x, &t0)
    62  
    63  	// Step 8: t4 = x^0x19
    64  	t4.Mul(&result, &t2)
    65  
    66  	// Step 9: t6 = x^0x22
    67  	t6.CyclotomicSquare(&t2)
    68  
    69  	// Step 10: t1 = x^0x27
    70  	t1.Mul(&t0, &t1)
    71  
    72  	// Step 11: t0 = x^0x29
    73  	t0.Mul(&t3, &t1)
    74  
    75  	// Step 17: t6 = x^0x880
    76  	t6.nSquare(6)
    77  
    78  	// Step 18: t5 = x^0x884
    79  	t5.Mul(&t5, &t6)
    80  
    81  	// Step 19: t5 = x^0x89d
    82  	t5.Mul(&t4, &t5)
    83  
    84  	// Step 26: t5 = x^0x44e80
    85  	t5.nSquare(7)
    86  
    87  	// Step 27: t4 = x^0x44e99
    88  	t4.Mul(&t4, &t5)
    89  
    90  	// Step 35: t4 = x^0x44e9900
    91  	t4.nSquare(8)
    92  
    93  	// Step 36: t4 = x^0x44e9929
    94  	t4.Mul(&t0, &t4)
    95  
    96  	// Step 37: t3 = x^0x44e992b
    97  	t3.Mul(&t3, &t4)
    98  
    99  	// Step 43: t3 = x^0x113a64ac0
   100  	t3.nSquare(6)
   101  
   102  	// Step 44: t2 = x^0x113a64ad1
   103  	t2.Mul(&t2, &t3)
   104  
   105  	// Step 52: t2 = x^0x113a64ad100
   106  	t2.nSquare(8)
   107  
   108  	// Step 53: t2 = x^0x113a64ad129
   109  	t2.Mul(&t0, &t2)
   110  
   111  	// Step 59: t2 = x^0x44e992b44a40
   112  	t2.nSquare(6)
   113  
   114  	// Step 60: t2 = x^0x44e992b44a69
   115  	t2.Mul(&t0, &t2)
   116  
   117  	// Step 70: t2 = x^0x113a64ad129a400
   118  	t2.nSquare(10)
   119  
   120  	// Step 71: t1 = x^0x113a64ad129a427
   121  	t1.Mul(&t1, &t2)
   122  
   123  	// Step 77: t1 = x^0x44e992b44a6909c0
   124  	t1.nSquare(6)
   125  
   126  	// Step 78: t0 = x^0x44e992b44a6909e9
   127  	t0.Mul(&t0, &t1)
   128  
   129  	// Step 79: result = x^0x44e992b44a6909f1
   130  	z.Mul(&result, &t0)
   131  
   132  	return z
   133  }
   134  
   135  // MulBy034 multiplication by sparse element (c0,0,0,c3,c4,0)
   136  func (z *E12) MulBy034(c0, c3, c4 *E2) *E12 {
   137  
   138  	var a, b, d E6
   139  
   140  	a.MulByE2(&z.C0, c0)
   141  
   142  	b.Set(&z.C1)
   143  	b.MulBy01(c3, c4)
   144  
   145  	var d0 E2
   146  	d0.Add(c0, c3)
   147  	d.Add(&z.C0, &z.C1)
   148  	d.MulBy01(&d0, c4)
   149  
   150  	z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d)
   151  	z.C0.MulByNonResidue(&b).Add(&z.C0, &a)
   152  
   153  	return z
   154  }
   155  
   156  // MulBy34 multiplication by sparse element (1,0,0,c3,c4,0)
   157  func (z *E12) MulBy34(c3, c4 *E2) *E12 {
   158  
   159  	var a, b, d E6
   160  
   161  	a.Set(&z.C0)
   162  
   163  	b.Set(&z.C1)
   164  	b.MulBy01(c3, c4)
   165  
   166  	var d0 E2
   167  	d0.SetOne().Add(&d0, c3)
   168  	d.Add(&z.C0, &z.C1)
   169  	d.MulBy01(&d0, c4)
   170  
   171  	z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d)
   172  	z.C0.MulByNonResidue(&b).Add(&z.C0, &a)
   173  
   174  	return z
   175  }
   176  
   177  // Mul034By034 multiplication of sparse element (c0,0,0,c3,c4,0) by sparse element (d0,0,0,d3,d4,0)
   178  func Mul034By034(d0, d3, d4, c0, c3, c4 *E2) [5]E2 {
   179  	var z00, tmp, x0, x3, x4, x04, x03, x34 E2
   180  	x0.Mul(c0, d0)
   181  	x3.Mul(c3, d3)
   182  	x4.Mul(c4, d4)
   183  	tmp.Add(c0, c4)
   184  	x04.Add(d0, d4).
   185  		Mul(&x04, &tmp).
   186  		Sub(&x04, &x0).
   187  		Sub(&x04, &x4)
   188  	tmp.Add(c0, c3)
   189  	x03.Add(d0, d3).
   190  		Mul(&x03, &tmp).
   191  		Sub(&x03, &x0).
   192  		Sub(&x03, &x3)
   193  	tmp.Add(c3, c4)
   194  	x34.Add(d3, d4).
   195  		Mul(&x34, &tmp).
   196  		Sub(&x34, &x3).
   197  		Sub(&x34, &x4)
   198  
   199  	z00.MulByNonResidue(&x4).
   200  		Add(&z00, &x0)
   201  
   202  	return [5]E2{z00, x3, x34, x03, x04}
   203  }
   204  
   205  // Mul34By34 multiplication of sparse element (1,0,0,c3,c4,0) by sparse element (1,0,0,d3,d4,0)
   206  func Mul34By34(d3, d4, c3, c4 *E2) [5]E2 {
   207  	var z00, tmp, x0, x3, x4, x04, x03, x34 E2
   208  	x3.Mul(c3, d3)
   209  	x4.Mul(c4, d4)
   210  	x04.Add(c4, d4)
   211  	x03.Add(c3, d3)
   212  	tmp.Add(c3, c4)
   213  	x34.Add(d3, d4).
   214  		Mul(&x34, &tmp).
   215  		Sub(&x34, &x3).
   216  		Sub(&x34, &x4)
   217  
   218  	x0.SetOne()
   219  	z00.MulByNonResidue(&x4).
   220  		Add(&z00, &x0)
   221  
   222  	return [5]E2{z00, x3, x34, x03, x04}
   223  }
   224  
   225  // MulBy01234 multiplies z by an E12 sparse element of the form (x0, x1, x2, x3, x4, 0)
   226  func (z *E12) MulBy01234(x *[5]E2) *E12 {
   227  	var c1, a, b, c, z0, z1 E6
   228  	c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
   229  	c1.B0 = x[3]
   230  	c1.B1 = x[4]
   231  	a.Add(&z.C0, &z.C1)
   232  	b.Add(c0, &c1)
   233  	a.Mul(&a, &b)
   234  	b.Mul(&z.C0, c0)
   235  	c.Set(&z.C1).MulBy01(&x[3], &x[4])
   236  	z1.Sub(&a, &b)
   237  	z1.Sub(&z1, &c)
   238  	z0.MulByNonResidue(&c)
   239  	z0.Add(&z0, &b)
   240  
   241  	z.C0 = z0
   242  	z.C1 = z1
   243  
   244  	return z
   245  }