github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/cloudflare/gfp2.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:36</date>
    10  //</624342624991449088>
    11  
    12  package bn256
    13  
    14  //有关所用算法的详细信息,请参阅
    15  //配对友好字段,Devegili等人
    16  //http://eprint.iacr.org/2006/471.pdf。
    17  
    18  //gfp2实现了一个大小为p²的字段作为基字段的二次扩展
    19  //其中,我=-1。
    20  type gfP2 struct {
    21  x, y gfP //值是X+Y。
    22  }
    23  
    24  func gfP2Decode(in *gfP2) *gfP2 {
    25  	out := &gfP2{}
    26  	montDecode(&out.x, &in.x)
    27  	montDecode(&out.y, &in.y)
    28  	return out
    29  }
    30  
    31  func (e *gfP2) String() string {
    32  	return "(" + e.x.String() + ", " + e.y.String() + ")"
    33  }
    34  
    35  func (e *gfP2) Set(a *gfP2) *gfP2 {
    36  	e.x.Set(&a.x)
    37  	e.y.Set(&a.y)
    38  	return e
    39  }
    40  
    41  func (e *gfP2) SetZero() *gfP2 {
    42  	e.x = gfP{0}
    43  	e.y = gfP{0}
    44  	return e
    45  }
    46  
    47  func (e *gfP2) SetOne() *gfP2 {
    48  	e.x = gfP{0}
    49  	e.y = *newGFp(1)
    50  	return e
    51  }
    52  
    53  func (e *gfP2) IsZero() bool {
    54  	zero := gfP{0}
    55  	return e.x == zero && e.y == zero
    56  }
    57  
    58  func (e *gfP2) IsOne() bool {
    59  	zero, one := gfP{0}, *newGFp(1)
    60  	return e.x == zero && e.y == one
    61  }
    62  
    63  func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
    64  	e.y.Set(&a.y)
    65  	gfpNeg(&e.x, &a.x)
    66  	return e
    67  }
    68  
    69  func (e *gfP2) Neg(a *gfP2) *gfP2 {
    70  	gfpNeg(&e.x, &a.x)
    71  	gfpNeg(&e.y, &a.y)
    72  	return e
    73  }
    74  
    75  func (e *gfP2) Add(a, b *gfP2) *gfP2 {
    76  	gfpAdd(&e.x, &a.x, &b.x)
    77  	gfpAdd(&e.y, &a.y, &b.y)
    78  	return e
    79  }
    80  
    81  func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
    82  	gfpSub(&e.x, &a.x, &b.x)
    83  	gfpSub(&e.y, &a.y, &b.y)
    84  	return e
    85  }
    86  
    87  //参见“配对友好字段中的乘法和平方”,
    88  //http://eprint.iacr.org/2006/471.pdf
    89  func (e *gfP2) Mul(a, b *gfP2) *gfP2 {
    90  	tx, t := &gfP{}, &gfP{}
    91  	gfpMul(tx, &a.x, &b.y)
    92  	gfpMul(t, &b.x, &a.y)
    93  	gfpAdd(tx, tx, t)
    94  
    95  	ty := &gfP{}
    96  	gfpMul(ty, &a.y, &b.y)
    97  	gfpMul(t, &a.x, &b.x)
    98  	gfpSub(ty, ty, t)
    99  
   100  	e.x.Set(tx)
   101  	e.y.Set(ty)
   102  	return e
   103  }
   104  
   105  func (e *gfP2) MulScalar(a *gfP2, b *gfP) *gfP2 {
   106  	gfpMul(&e.x, &a.x, b)
   107  	gfpMul(&e.y, &a.y, b)
   108  	return e
   109  }
   110  
   111  //mulxi设置e=ξa,其中ξ=i+9,然后返回e。
   112  func (e *gfP2) MulXi(a *gfP2) *gfP2 {
   113  //(X+Y)(i+9)=(9x+y)i+(9y- x)
   114  	tx := &gfP{}
   115  	gfpAdd(tx, &a.x, &a.x)
   116  	gfpAdd(tx, tx, tx)
   117  	gfpAdd(tx, tx, tx)
   118  	gfpAdd(tx, tx, &a.x)
   119  
   120  	gfpAdd(tx, tx, &a.y)
   121  
   122  	ty := &gfP{}
   123  	gfpAdd(ty, &a.y, &a.y)
   124  	gfpAdd(ty, ty, ty)
   125  	gfpAdd(ty, ty, ty)
   126  	gfpAdd(ty, ty, &a.y)
   127  
   128  	gfpSub(ty, ty, &a.x)
   129  
   130  	e.x.Set(tx)
   131  	e.y.Set(ty)
   132  	return e
   133  }
   134  
   135  func (e *gfP2) Square(a *gfP2) *gfP2 {
   136  //复杂平方算法:
   137  //(X+Y)=(x+y)(y- x)+2*i*x*y
   138  	tx, ty := &gfP{}, &gfP{}
   139  	gfpSub(tx, &a.y, &a.x)
   140  	gfpAdd(ty, &a.x, &a.y)
   141  	gfpMul(ty, tx, ty)
   142  
   143  	gfpMul(tx, &a.x, &a.y)
   144  	gfpAdd(tx, tx, tx)
   145  
   146  	e.x.Set(tx)
   147  	e.y.Set(ty)
   148  	return e
   149  }
   150  
   151  func (e *gfP2) Invert(a *gfP2) *gfP2 {
   152  //见“实现密码配对”,M.Scott,第3.2节。
   153  //ftp://136.206.11.249/pub/crypto/pairing.pdf文件
   154  	t1, t2 := &gfP{}, &gfP{}
   155  	gfpMul(t1, &a.x, &a.x)
   156  	gfpMul(t2, &a.y, &a.y)
   157  	gfpAdd(t1, t1, t2)
   158  
   159  	inv := &gfP{}
   160  	inv.Invert(t1)
   161  
   162  	gfpNeg(t1, &a.x)
   163  
   164  	gfpMul(&e.x, t1, inv)
   165  	gfpMul(&e.y, &a.y, inv)
   166  	return e
   167  }
   168