github.com/cloudflare/circl@v1.5.0/ecc/bls12381/ec2.go (about)

     1  package bls12381
     2  
     3  import "github.com/cloudflare/circl/ecc/bls12381/ff"
     4  
     5  func doubleAndLine(P *G2, l *line) {
     6  	// Reference:
     7  	//   "Faster Pairing Computations on Curves with High-Degree Twists" by
     8  	//   Costello-Lange-Naehrig. [Sec. 5] (eprint.iacr.org/2009/615).
     9  	//   "Complete addition formulas for prime order elliptic curves" by
    10  	//   Costello-Renes-Batina. [Alg.9] (eprint.iacr.org/2015/1060).
    11  	var R G2
    12  	X, Y, Z := &P.x, &P.y, &P.z
    13  	X3, Y3, Z3 := &R.x, &R.y, &R.z
    14  	isDoubLine := l != nil
    15  	_3B := &g2Params._3b
    16  	var A, B, C, D, E, F, G, T ff.Fp2
    17  	B.Sqr(Y)       // 1. B = Y1^2
    18  	C.Sqr(Z)       // 2. C = Z1^2
    19  	D.Mul(_3B, &C) // 3. D = 3b*C
    20  	F.Add(Y, Z)    // 4. F = (Y1+Z1)
    21  	F.Sqr(&F)      //    F = (Y1+Z1)^2
    22  	F.Sub(&F, &B)  //    F = (Y1+Z1)^2-B
    23  	F.Sub(&F, &C)  //    F = (Y1+Z1)^2-B-C
    24  	if isDoubLine {
    25  		A.Sqr(X)            // 5.  A  = X1^2
    26  		E.Add(X, Y)         //     E  = (X1+Y1)
    27  		E.Sqr(&E)           //     E  = (X1+Y1)^2
    28  		E.Sub(&E, &A)       //     E  = (X1+Y1)^2-A
    29  		E.Sub(&E, &B)       //     E  = (X1+Y1)^2-A-B = 2X*Y
    30  		l[0].Add(&A, &A)    // 5a. l0 = 2A
    31  		l[0].Add(&l[0], &A) //     l0 = 3A = 3X1^2
    32  		l[1] = F            // 5b. l1 = F
    33  		l[1].Neg()          //     l1 = -F = -2Y1Z1
    34  		l[2].Sub(&D, &B)    // 5c. l2 = D-B = 3b*Z1^2-Y1^2
    35  	} else {
    36  		E.Mul(X, Y)   // 5. E = X*Y
    37  		E.Add(&E, &E) //    E = 2X*Y
    38  	}
    39  	T.Add(&D, &D)  // 6.  T  = 2D
    40  	G.Add(&T, &D)  // 7.  G  = 3D
    41  	X3.Sub(&B, &G) // 8.  X3 = (B-G)
    42  	X3.Mul(X3, &E) //     X3 = E*(B-G)
    43  	T.Sqr(&T)      // 9 .  T = 4D^2
    44  	Y3.Add(&B, &G) // 10. Y3 = (B+G)
    45  	Y3.Sqr(Y3)     //     Y3 = (B+G)^2
    46  	Y3.Sub(Y3, &T) //     Y3 = (B+G)^2-4D^2
    47  	Y3.Sub(Y3, &T) //     Y3 = (B+G)^2-8D^2
    48  	Y3.Sub(Y3, &T) //     Y3 = (B+G)^2-12D^2
    49  	Z3.Mul(&B, &F) // 11. Z3 = B*F
    50  	Z3.Add(Z3, Z3) //     Z3 = 2B*F
    51  	Z3.Add(Z3, Z3) //     Z3 = 4B*F
    52  	*P = R
    53  }
    54  
    55  func addAndLine(PQ, P, Q *G2, l *line) {
    56  	// Reference:
    57  	//   "Faster Pairing Computations on Curves with High-Degree Twists" by
    58  	//   Costello-Lange-Naehrig. [Sec. 5] (eprint.iacr.org/2009/615).
    59  	//   "Complete addition formulas for prime order elliptic curves" by
    60  	//   Costello-Renes-Batina. [Alg.7] (eprint.iacr.org/2015/1060).
    61  	var R G2
    62  	X1, Y1, Z1 := &P.x, &P.y, &P.z
    63  	X2, Y2, Z2 := &Q.x, &Q.y, &Q.z
    64  	X3, Y3, Z3 := &R.x, &R.y, &R.z
    65  	_3B := &g2Params._3b
    66  	isAddLine := l != nil
    67  	var X1X2, Y1Y2, Z1Z2, _3bZ1Z2 ff.Fp2
    68  	var A, B, C, D, E, F, G ff.Fp2
    69  	t0, t1 := &ff.Fp2{}, &ff.Fp2{}
    70  
    71  	X1X2.Mul(X1, X2)
    72  	Y1Y2.Mul(Y1, Y2)
    73  	Z1Z2.Mul(Z1, Z2)
    74  	_3bZ1Z2.Mul(&Z1Z2, _3B)
    75  
    76  	A.Add(&X1X2, &X1X2)    // A = 2X1X2
    77  	A.Add(&A, &X1X2)       //   = 3X1X2
    78  	B.Add(&Y1Y2, &_3bZ1Z2) // B = Y1Y2+3bZ1Z2
    79  	C.Sub(&Y1Y2, &_3bZ1Z2) // C = Y1Y2-3bZ1Z2
    80  
    81  	t0.Add(X1, Y1)   // t0 = (X1 + Y1)
    82  	D.Add(X2, Y2)    // D  = (X2 + Y2)
    83  	D.Mul(&D, t0)    //    = X1X2 + X1Y2 + X2Y1 + Y1Y2
    84  	D.Sub(&D, &X1X2) //    = X1Y2 + X2Y1 + Y1Y2
    85  	D.Sub(&D, &Y1Y2) //    = X1Y2 + X2Y1
    86  
    87  	if isAddLine {
    88  		var EE, FF ff.Fp2
    89  		t0.Mul(Y1, Z2) // t0 = Y1Z2
    90  		t1.Mul(Y2, Z1) // t1 = Y2Z1
    91  		E.Add(t0, t1)  // E  = Y1Z2 + Y2Z1
    92  		EE.Sub(t0, t1) // EE = Y1Z2 - Y2Z1
    93  
    94  		t0.Mul(X1, Z2) // t0 = X1Z2
    95  		t1.Mul(X2, Z1) // t1 = X2Z1
    96  		F.Add(t0, t1)  // F  = X1Z2 + X2Z1
    97  		FF.Sub(t0, t1) // FF = X1Z2 - X2Z1
    98  
    99  		l[0].Mul(&EE, Z2)   // l0 = (Y1Z2 - Y2Z1)*Z2
   100  		l[0].Neg()          //    = -(Y1Z2 - Y2Z1)*Z2
   101  		l[1].Mul(&FF, Z2)   // l1 = (X1Z2 - X2Z1)*Z2
   102  		t0.Mul(&FF, Y2)     // t0 = (X1Z2 - X2Z1)*Y2
   103  		l[2].Mul(&EE, X2)   // l2 = (Y1Z2 - Y2Z1)*X2
   104  		l[2].Sub(&l[2], t0) //    = (Y1Z2 - Y2Z1)*X2 - (X1Z2 - X2Z1)*Y2
   105  	} else {
   106  		t0.Add(Y1, Z1)   // t0 = (Y1 + Z1)
   107  		t1.Add(Y2, Z2)   // t1 = (Y2 + Z2)
   108  		E.Mul(t0, t1)    // E  = Y1Y2 + Y1Z2 + Y2Z1 + Z1Z2
   109  		E.Sub(&E, &Y1Y2) //    = Y1Z2 + Y2Z1 + Z1Z2
   110  		E.Sub(&E, &Z1Z2) //    = Y1Z2 + Y2Z1
   111  
   112  		t0.Add(X1, Z1)   // t0 = (X1 + Z1)
   113  		t1.Add(X2, Z2)   // t1 = (X2 + Z2)
   114  		F.Mul(t0, t1)    // F  = X1X2 + X1Z2 + X2Z1 + Z1Z2
   115  		F.Sub(&F, &X1X2) //    = X1Z2 + X2Z1 + Z1Z2
   116  		F.Sub(&F, &Z1Z2) //    = X1Z2 + X2Z1
   117  	}
   118  	G.Mul(&F, _3B) // G = 3b*F
   119  
   120  	t0.Mul(&E, &G) // t0 = E*G
   121  	X3.Mul(&D, &C) // X3 = D*C
   122  	X3.Sub(X3, t0) //    = D*C - E*G
   123  
   124  	t0.Mul(&A, &G) // t0 = A*G
   125  	Y3.Mul(&B, &C) // Y3 = B*C
   126  	Y3.Add(Y3, t0) //    = B*C + A*G
   127  
   128  	t0.Mul(&A, &D) // t0 = A*D
   129  	Z3.Mul(&E, &B) // Z3 = E*B
   130  	Z3.Add(Z3, t0) //    = E*B + A*D
   131  
   132  	*PQ = R
   133  }