github.com/amazechain/amc@v0.1.3/common/crypto/bn256/cloudflare/gfp2.go (about)

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