github.com/ebceco/ebc@v1.8.19-0.20190309150932-8cb0b9e06484/crypto/bn256/cloudflare/gfp2.go (about)

     1  package bn256
     2  
     3  // For details of the algorithms used, see "Multiplication and Squaring on
     4  // Pairing-Friendly Fields, Devegili et al.
     5  // http://eprint.iacr.org/2006/471.pdf.
     6  
     7  // gfP2 implements a field of size p² as a quadratic extension of the base field
     8  // where i²=-1.
     9  type gfP2 struct {
    10  	x, y gfP // value is xi+y.
    11  }
    12  
    13  func gfP2Decode(in *gfP2) *gfP2 {
    14  	out := &gfP2{}
    15  	montDecode(&out.x, &in.x)
    16  	montDecode(&out.y, &in.y)
    17  	return out
    18  }
    19  
    20  func (e *gfP2) String() string {
    21  	return "(" + e.x.String() + ", " + e.y.String() + ")"
    22  }
    23  
    24  func (e *gfP2) Set(a *gfP2) *gfP2 {
    25  	e.x.Set(&a.x)
    26  	e.y.Set(&a.y)
    27  	return e
    28  }
    29  
    30  func (e *gfP2) SetZero() *gfP2 {
    31  	e.x = gfP{0}
    32  	e.y = gfP{0}
    33  	return e
    34  }
    35  
    36  func (e *gfP2) SetOne() *gfP2 {
    37  	e.x = gfP{0}
    38  	e.y = *newGFp(1)
    39  	return e
    40  }
    41  
    42  func (e *gfP2) IsZero() bool {
    43  	zero := gfP{0}
    44  	return e.x == zero && e.y == zero
    45  }
    46  
    47  func (e *gfP2) IsOne() bool {
    48  	zero, one := gfP{0}, *newGFp(1)
    49  	return e.x == zero && e.y == one
    50  }
    51  
    52  func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
    53  	e.y.Set(&a.y)
    54  	gfpNeg(&e.x, &a.x)
    55  	return e
    56  }
    57  
    58  func (e *gfP2) Neg(a *gfP2) *gfP2 {
    59  	gfpNeg(&e.x, &a.x)
    60  	gfpNeg(&e.y, &a.y)
    61  	return e
    62  }
    63  
    64  func (e *gfP2) Add(a, b *gfP2) *gfP2 {
    65  	gfpAdd(&e.x, &a.x, &b.x)
    66  	gfpAdd(&e.y, &a.y, &b.y)
    67  	return e
    68  }
    69  
    70  func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
    71  	gfpSub(&e.x, &a.x, &b.x)
    72  	gfpSub(&e.y, &a.y, &b.y)
    73  	return e
    74  }
    75  
    76  // See "Multiplication and Squaring in Pairing-Friendly Fields",
    77  // http://eprint.iacr.org/2006/471.pdf
    78  func (e *gfP2) Mul(a, b *gfP2) *gfP2 {
    79  	tx, t := &gfP{}, &gfP{}
    80  	gfpMul(tx, &a.x, &b.y)
    81  	gfpMul(t, &b.x, &a.y)
    82  	gfpAdd(tx, tx, t)
    83  
    84  	ty := &gfP{}
    85  	gfpMul(ty, &a.y, &b.y)
    86  	gfpMul(t, &a.x, &b.x)
    87  	gfpSub(ty, ty, t)
    88  
    89  	e.x.Set(tx)
    90  	e.y.Set(ty)
    91  	return e
    92  }
    93  
    94  func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 {
    95  	gfpMul(&e.x, &a.x, b)
    96  	gfpMul(&e.y, &a.y, b)
    97  	return e
    98  }
    99  
   100  // MulXi sets e=ξa where ξ=i+9 and then returns e.
   101  func (e *gfP2) MulXi(a *gfP2) *gfP2 {
   102  	// (xi+y)(i+9) = (9x+y)i+(9y-x)
   103  	tx := &gfP{}
   104  	gfpAdd(tx, &a.x, &a.x)
   105  	gfpAdd(tx, tx, tx)
   106  	gfpAdd(tx, tx, tx)
   107  	gfpAdd(tx, tx, &a.x)
   108  
   109  	gfpAdd(tx, tx, &a.y)
   110  
   111  	ty := &gfP{}
   112  	gfpAdd(ty, &a.y, &a.y)
   113  	gfpAdd(ty, ty, ty)
   114  	gfpAdd(ty, ty, ty)
   115  	gfpAdd(ty, ty, &a.y)
   116  
   117  	gfpSub(ty, ty, &a.x)
   118  
   119  	e.x.Set(tx)
   120  	e.y.Set(ty)
   121  	return e
   122  }
   123  
   124  func (e *gfP2) Square(a *gfP2) *gfP2 {
   125  	// Complex squaring algorithm:
   126  	// (xi+y)² = (x+y)(y-x) + 2*i*x*y
   127  	tx, ty := &gfP{}, &gfP{}
   128  	gfpSub(tx, &a.y, &a.x)
   129  	gfpAdd(ty, &a.x, &a.y)
   130  	gfpMul(ty, tx, ty)
   131  
   132  	gfpMul(tx, &a.x, &a.y)
   133  	gfpAdd(tx, tx, tx)
   134  
   135  	e.x.Set(tx)
   136  	e.y.Set(ty)
   137  	return e
   138  }
   139  
   140  func (e *gfP2) Invert(a *gfP2) *gfP2 {
   141  	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
   142  	// ftp://136.206.11.249/pub/crypto/pairings.pdf
   143  	t1, t2 := &gfP{}, &gfP{}
   144  	gfpMul(t1, &a.x, &a.x)
   145  	gfpMul(t2, &a.y, &a.y)
   146  	gfpAdd(t1, t1, t2)
   147  
   148  	inv := &gfP{}
   149  	inv.Invert(t1)
   150  
   151  	gfpNeg(t1, &a.x)
   152  
   153  	gfpMul(&e.x, t1, inv)
   154  	gfpMul(&e.y, &a.y, inv)
   155  	return e
   156  }