github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/crypto/bn256/cloudflare/gfp2.go (about)

     1  //  Copyright 2018 The go-ethereum Authors
     2  //  Copyright 2019 The go-aigar Authors
     3  //  This file is part of the go-aigar library.
     4  //
     5  //  The go-aigar library is free software: you can redistribute it and/or modify
     6  //  it under the terms of the GNU Lesser General Public License as published by
     7  //  the Free Software Foundation, either version 3 of the License, or
     8  //  (at your option) any later version.
     9  //
    10  //  The go-aigar library is distributed in the hope that it will be useful,
    11  //  but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  //  GNU Lesser General Public License for more details.
    14  //
    15  //  You should have received a copy of the GNU Lesser General Public License
    16  //  along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package bn256
    19  
    20  // For details of the algorithms used, see "Multiplication and Squaring on
    21  // Pairing-Friendly Fields, Devegili et al.
    22  // http://eprint.iacr.org/2006/471.pdf.
    23  
    24  // gfP2 implements a field of size p² as a quadratic extension of the base field
    25  // where i²=-1.
    26  type gfP2 struct {
    27  	x, y gfP // value is xi+y.
    28  }
    29  
    30  func gfP2Decode(in *gfP2) *gfP2 {
    31  	out := &gfP2{}
    32  	montDecode(&out.x, &in.x)
    33  	montDecode(&out.y, &in.y)
    34  	return out
    35  }
    36  
    37  func (e *gfP2) String() string {
    38  	return "(" + e.x.String() + ", " + e.y.String() + ")"
    39  }
    40  
    41  func (e *gfP2) Set(a *gfP2) *gfP2 {
    42  	e.x.Set(&a.x)
    43  	e.y.Set(&a.y)
    44  	return e
    45  }
    46  
    47  func (e *gfP2) SetZero() *gfP2 {
    48  	e.x = gfP{0}
    49  	e.y = gfP{0}
    50  	return e
    51  }
    52  
    53  func (e *gfP2) SetOne() *gfP2 {
    54  	e.x = gfP{0}
    55  	e.y = *newGFp(1)
    56  	return e
    57  }
    58  
    59  func (e *gfP2) IsZero() bool {
    60  	zero := gfP{0}
    61  	return e.x == zero && e.y == zero
    62  }
    63  
    64  func (e *gfP2) IsOne() bool {
    65  	zero, one := gfP{0}, *newGFp(1)
    66  	return e.x == zero && e.y == one
    67  }
    68  
    69  func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
    70  	e.y.Set(&a.y)
    71  	gfpNeg(&e.x, &a.x)
    72  	return e
    73  }
    74  
    75  func (e *gfP2) Neg(a *gfP2) *gfP2 {
    76  	gfpNeg(&e.x, &a.x)
    77  	gfpNeg(&e.y, &a.y)
    78  	return e
    79  }
    80  
    81  func (e *gfP2) Add(a, b *gfP2) *gfP2 {
    82  	gfpAdd(&e.x, &a.x, &b.x)
    83  	gfpAdd(&e.y, &a.y, &b.y)
    84  	return e
    85  }
    86  
    87  func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
    88  	gfpSub(&e.x, &a.x, &b.x)
    89  	gfpSub(&e.y, &a.y, &b.y)
    90  	return e
    91  }
    92  
    93  // See "Multiplication and Squaring in Pairing-Friendly Fields",
    94  // http://eprint.iacr.org/2006/471.pdf
    95  func (e *gfP2) Mul(a, b *gfP2) *gfP2 {
    96  	tx, t := &gfP{}, &gfP{}
    97  	gfpMul(tx, &a.x, &b.y)
    98  	gfpMul(t, &b.x, &a.y)
    99  	gfpAdd(tx, tx, t)
   100  
   101  	ty := &gfP{}
   102  	gfpMul(ty, &a.y, &b.y)
   103  	gfpMul(t, &a.x, &b.x)
   104  	gfpSub(ty, ty, t)
   105  
   106  	e.x.Set(tx)
   107  	e.y.Set(ty)
   108  	return e
   109  }
   110  
   111  func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 {
   112  	gfpMul(&e.x, &a.x, b)
   113  	gfpMul(&e.y, &a.y, b)
   114  	return e
   115  }
   116  
   117  // MulXi sets e=ξa where ξ=i+9 and then returns e.
   118  func (e *gfP2) MulXi(a *gfP2) *gfP2 {
   119  	// (xi+y)(i+9) = (9x+y)i+(9y-x)
   120  	tx := &gfP{}
   121  	gfpAdd(tx, &a.x, &a.x)
   122  	gfpAdd(tx, tx, tx)
   123  	gfpAdd(tx, tx, tx)
   124  	gfpAdd(tx, tx, &a.x)
   125  
   126  	gfpAdd(tx, tx, &a.y)
   127  
   128  	ty := &gfP{}
   129  	gfpAdd(ty, &a.y, &a.y)
   130  	gfpAdd(ty, ty, ty)
   131  	gfpAdd(ty, ty, ty)
   132  	gfpAdd(ty, ty, &a.y)
   133  
   134  	gfpSub(ty, ty, &a.x)
   135  
   136  	e.x.Set(tx)
   137  	e.y.Set(ty)
   138  	return e
   139  }
   140  
   141  func (e *gfP2) Square(a *gfP2) *gfP2 {
   142  	// Complex squaring algorithm:
   143  	// (xi+y)² = (x+y)(y-x) + 2*i*x*y
   144  	tx, ty := &gfP{}, &gfP{}
   145  	gfpSub(tx, &a.y, &a.x)
   146  	gfpAdd(ty, &a.x, &a.y)
   147  	gfpMul(ty, tx, ty)
   148  
   149  	gfpMul(tx, &a.x, &a.y)
   150  	gfpAdd(tx, tx, tx)
   151  
   152  	e.x.Set(tx)
   153  	e.y.Set(ty)
   154  	return e
   155  }
   156  
   157  func (e *gfP2) Invert(a *gfP2) *gfP2 {
   158  	// See "Implementing cryptographic pairings", M. Scott, section 3.2.
   159  	// ftp://136.206.11.249/pub/crypto/pairings.pdf
   160  	t1, t2 := &gfP{}, &gfP{}
   161  	gfpMul(t1, &a.x, &a.x)
   162  	gfpMul(t2, &a.y, &a.y)
   163  	gfpAdd(t1, t1, t2)
   164  
   165  	inv := &gfP{}
   166  	inv.Invert(t1)
   167  
   168  	gfpNeg(t1, &a.x)
   169  
   170  	gfpMul(&e.x, t1, inv)
   171  	gfpMul(&e.y, &a.y, inv)
   172  	return e
   173  }