github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/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  	// const tAbsVal uint64 = 9586122913090633729
    18  	// tAbsVal in binary: 1000010100001000110000000000000000000000000000000000000000000001
    19  	// drop the low 46 bits (all 0 except the least significant bit): 100001010000100011 = 136227
    20  	// Shortest addition chains can be found at https://wwwhomes.uni-bielefeld.de/achim/addition_chain.html
    21  
    22  	var result, x33 E12
    23  
    24  	// a shortest addition chain for 136227
    25  	result.Set(x)
    26  	result.nSquare(5)
    27  	result.Mul(&result, x)
    28  	x33.Set(&result)
    29  	result.nSquare(7)
    30  	result.Mul(&result, &x33)
    31  	result.nSquare(4)
    32  	result.Mul(&result, x)
    33  	result.CyclotomicSquare(&result)
    34  	result.Mul(&result, x)
    35  
    36  	// the remaining 46 bits
    37  	result.nSquareCompressed(46)
    38  	result.DecompressKarabina(&result)
    39  	result.Mul(&result, x)
    40  
    41  	z.Set(&result)
    42  	return z
    43  }
    44  
    45  // MulBy034 multiplication by sparse element (c0,0,0,c3,c4,0)
    46  func (z *E12) MulBy034(c0, c3, c4 *E2) *E12 {
    47  
    48  	var a, b, d E6
    49  
    50  	a.MulByE2(&z.C0, c0)
    51  
    52  	b.Set(&z.C1)
    53  	b.MulBy01(c3, c4)
    54  
    55  	var d0 E2
    56  	d0.Add(c0, c3)
    57  	d.Add(&z.C0, &z.C1)
    58  	d.MulBy01(&d0, c4)
    59  
    60  	z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d)
    61  	z.C0.MulByNonResidue(&b).Add(&z.C0, &a)
    62  
    63  	return z
    64  }
    65  
    66  // MulBy34 multiplication by sparse element (1,0,0,c3,c4,0)
    67  func (z *E12) MulBy34(c3, c4 *E2) *E12 {
    68  
    69  	var a, b, d E6
    70  
    71  	a.Set(&z.C0)
    72  
    73  	b.Set(&z.C1)
    74  	b.MulBy01(c3, c4)
    75  
    76  	var d0 E2
    77  	d0.SetOne().Add(&d0, c3)
    78  	d.Add(&z.C0, &z.C1)
    79  	d.MulBy01(&d0, c4)
    80  
    81  	z.C1.Add(&a, &b).Neg(&z.C1).Add(&z.C1, &d)
    82  	z.C0.MulByNonResidue(&b).Add(&z.C0, &a)
    83  
    84  	return z
    85  }
    86  
    87  // Mul034By034 multiplication of sparse element (c0,0,0,c3,c4,0) by sparse element (d0,0,0,d3,d4,0)
    88  func Mul034By034(d0, d3, d4, c0, c3, c4 *E2) [5]E2 {
    89  	var z00, tmp, x0, x3, x4, x04, x03, x34 E2
    90  	x0.Mul(c0, d0)
    91  	x3.Mul(c3, d3)
    92  	x4.Mul(c4, d4)
    93  	tmp.Add(c0, c4)
    94  	x04.Add(d0, d4).
    95  		Mul(&x04, &tmp).
    96  		Sub(&x04, &x0).
    97  		Sub(&x04, &x4)
    98  	tmp.Add(c0, c3)
    99  	x03.Add(d0, d3).
   100  		Mul(&x03, &tmp).
   101  		Sub(&x03, &x0).
   102  		Sub(&x03, &x3)
   103  	tmp.Add(c3, c4)
   104  	x34.Add(d3, d4).
   105  		Mul(&x34, &tmp).
   106  		Sub(&x34, &x3).
   107  		Sub(&x34, &x4)
   108  
   109  	z00.MulByNonResidue(&x4).
   110  		Add(&z00, &x0)
   111  
   112  	return [5]E2{z00, x3, x34, x03, x04}
   113  }
   114  
   115  // Mul34By34 multiplication of sparse element (1,0,0,c3,c4,0) by sparse element (1,0,0,d3,d4,0)
   116  func Mul34By34(d3, d4, c3, c4 *E2) [5]E2 {
   117  	var z00, tmp, x0, x3, x4, x04, x03, x34 E2
   118  	x3.Mul(c3, d3)
   119  	x4.Mul(c4, d4)
   120  	x04.Add(c4, d4)
   121  	x03.Add(c3, d3)
   122  	tmp.Add(c3, c4)
   123  	x34.Add(d3, d4).
   124  		Mul(&x34, &tmp).
   125  		Sub(&x34, &x3).
   126  		Sub(&x34, &x4)
   127  
   128  	x0.SetOne()
   129  	z00.MulByNonResidue(&x4).
   130  		Add(&z00, &x0)
   131  
   132  	return [5]E2{z00, x3, x34, x03, x04}
   133  }
   134  
   135  // MulBy01234 multiplies z by an E12 sparse element of the form (x0, x1, x2, x3, x4, 0)
   136  func (z *E12) MulBy01234(x *[5]E2) *E12 {
   137  	var c1, a, b, c, z0, z1 E6
   138  	c0 := &E6{B0: x[0], B1: x[1], B2: x[2]}
   139  	c1.B0 = x[3]
   140  	c1.B1 = x[4]
   141  	a.Add(&z.C0, &z.C1)
   142  	b.Add(c0, &c1)
   143  	a.Mul(&a, &b)
   144  	b.Mul(&z.C0, c0)
   145  	c.Set(&z.C1).MulBy01(&x[3], &x[4])
   146  	z1.Sub(&a, &b)
   147  	z1.Sub(&z1, &c)
   148  	z0.MulByNonResidue(&c)
   149  	z0.Add(&z0, &b)
   150  
   151  	z.C0 = z0
   152  	z.C1 = z1
   153  
   154  	return z
   155  }