github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-317/internal/fptower/e24_pairing.go (about)

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