github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/gfp2.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2012 Go作者。版权所有。
    10  //此源代码的使用受BSD样式的控制
    11  //可以在许可文件中找到的许可证。
    12  
    13  package bn256
    14  
    15  //有关所用算法的详细信息,请参阅
    16  //配对友好字段,Devegili等人
    17  //http://eprint.iacr.org/2006/471.pdf。
    18  
    19  import (
    20  	"math/big"
    21  )
    22  
    23  //gfp2实现了一个大小为p²的字段作为基的二次扩展
    24  //字段,其中i?=-1。
    25  type gfP2 struct {
    26  x, y *big.Int //值是X+Y。
    27  }
    28  
    29  func newGFp2(pool *bnPool) *gfP2 {
    30  	return &gfP2{pool.Get(), pool.Get()}
    31  }
    32  
    33  func (e *gfP2) String() string {
    34  	x := new(big.Int).Mod(e.x, P)
    35  	y := new(big.Int).Mod(e.y, P)
    36  	return "(" + x.String() + "," + y.String() + ")"
    37  }
    38  
    39  func (e *gfP2) Put(pool *bnPool) {
    40  	pool.Put(e.x)
    41  	pool.Put(e.y)
    42  }
    43  
    44  func (e *gfP2) Set(a *gfP2) *gfP2 {
    45  	e.x.Set(a.x)
    46  	e.y.Set(a.y)
    47  	return e
    48  }
    49  
    50  func (e *gfP2) SetZero() *gfP2 {
    51  	e.x.SetInt64(0)
    52  	e.y.SetInt64(0)
    53  	return e
    54  }
    55  
    56  func (e *gfP2) SetOne() *gfP2 {
    57  	e.x.SetInt64(0)
    58  	e.y.SetInt64(1)
    59  	return e
    60  }
    61  
    62  func (e *gfP2) Minimal() {
    63  	if e.x.Sign() < 0 || e.x.Cmp(P) >= 0 {
    64  		e.x.Mod(e.x, P)
    65  	}
    66  	if e.y.Sign() < 0 || e.y.Cmp(P) >= 0 {
    67  		e.y.Mod(e.y, P)
    68  	}
    69  }
    70  
    71  func (e *gfP2) IsZero() bool {
    72  	return e.x.Sign() == 0 && e.y.Sign() == 0
    73  }
    74  
    75  func (e *gfP2) IsOne() bool {
    76  	if e.x.Sign() != 0 {
    77  		return false
    78  	}
    79  	words := e.y.Bits()
    80  	return len(words) == 1 && words[0] == 1
    81  }
    82  
    83  func (e *gfP2) Conjugate(a *gfP2) *gfP2 {
    84  	e.y.Set(a.y)
    85  	e.x.Neg(a.x)
    86  	return e
    87  }
    88  
    89  func (e *gfP2) Negative(a *gfP2) *gfP2 {
    90  	e.x.Neg(a.x)
    91  	e.y.Neg(a.y)
    92  	return e
    93  }
    94  
    95  func (e *gfP2) Add(a, b *gfP2) *gfP2 {
    96  	e.x.Add(a.x, b.x)
    97  	e.y.Add(a.y, b.y)
    98  	return e
    99  }
   100  
   101  func (e *gfP2) Sub(a, b *gfP2) *gfP2 {
   102  	e.x.Sub(a.x, b.x)
   103  	e.y.Sub(a.y, b.y)
   104  	return e
   105  }
   106  
   107  func (e *gfP2) Double(a *gfP2) *gfP2 {
   108  	e.x.Lsh(a.x, 1)
   109  	e.y.Lsh(a.y, 1)
   110  	return e
   111  }
   112  
   113  func (c *gfP2) Exp(a *gfP2, power *big.Int, pool *bnPool) *gfP2 {
   114  	sum := newGFp2(pool)
   115  	sum.SetOne()
   116  	t := newGFp2(pool)
   117  
   118  	for i := power.BitLen() - 1; i >= 0; i-- {
   119  		t.Square(sum, pool)
   120  		if power.Bit(i) != 0 {
   121  			sum.Mul(t, a, pool)
   122  		} else {
   123  			sum.Set(t)
   124  		}
   125  	}
   126  
   127  	c.Set(sum)
   128  
   129  	sum.Put(pool)
   130  	t.Put(pool)
   131  
   132  	return c
   133  }
   134  
   135  //参见“配对友好字段中的乘法和平方”,
   136  //http://eprint.iacr.org/2006/471.pdf
   137  func (e *gfP2) Mul(a, b *gfP2, pool *bnPool) *gfP2 {
   138  	tx := pool.Get().Mul(a.x, b.y)
   139  	t := pool.Get().Mul(b.x, a.y)
   140  	tx.Add(tx, t)
   141  	tx.Mod(tx, P)
   142  
   143  	ty := pool.Get().Mul(a.y, b.y)
   144  	t.Mul(a.x, b.x)
   145  	ty.Sub(ty, t)
   146  	e.y.Mod(ty, P)
   147  	e.x.Set(tx)
   148  
   149  	pool.Put(tx)
   150  	pool.Put(ty)
   151  	pool.Put(t)
   152  
   153  	return e
   154  }
   155  
   156  func (e *gfP2) MulScalar(a *gfP2, b *big.Int) *gfP2 {
   157  	e.x.Mul(a.x, b)
   158  	e.y.Mul(a.y, b)
   159  	return e
   160  }
   161  
   162  //mulxi设置e=ξa,其中ξ=i+9,然后返回e。
   163  func (e *gfP2) MulXi(a *gfP2, pool *bnPool) *gfP2 {
   164  //(X+Y)(i+3)=(9x+y)i+(9y- x)
   165  	tx := pool.Get().Lsh(a.x, 3)
   166  	tx.Add(tx, a.x)
   167  	tx.Add(tx, a.y)
   168  
   169  	ty := pool.Get().Lsh(a.y, 3)
   170  	ty.Add(ty, a.y)
   171  	ty.Sub(ty, a.x)
   172  
   173  	e.x.Set(tx)
   174  	e.y.Set(ty)
   175  
   176  	pool.Put(tx)
   177  	pool.Put(ty)
   178  
   179  	return e
   180  }
   181  
   182  func (e *gfP2) Square(a *gfP2, pool *bnPool) *gfP2 {
   183  //复杂平方算法:
   184  //(X+B)=(x+y)(y- x)+2*i*x*y
   185  	t1 := pool.Get().Sub(a.y, a.x)
   186  	t2 := pool.Get().Add(a.x, a.y)
   187  	ty := pool.Get().Mul(t1, t2)
   188  	ty.Mod(ty, P)
   189  
   190  	t1.Mul(a.x, a.y)
   191  	t1.Lsh(t1, 1)
   192  
   193  	e.x.Mod(t1, P)
   194  	e.y.Set(ty)
   195  
   196  	pool.Put(t1)
   197  	pool.Put(t2)
   198  	pool.Put(ty)
   199  
   200  	return e
   201  }
   202  
   203  func (e *gfP2) Invert(a *gfP2, pool *bnPool) *gfP2 {
   204  //见“实现密码配对”,M.Scott,第3.2节。
   205  //ftp://136.206.11.249/pub/crypto/pairing.pdf文件
   206  	t := pool.Get()
   207  	t.Mul(a.y, a.y)
   208  	t2 := pool.Get()
   209  	t2.Mul(a.x, a.x)
   210  	t.Add(t, t2)
   211  
   212  	inv := pool.Get()
   213  	inv.ModInverse(t, P)
   214  
   215  	e.x.Neg(a.x)
   216  	e.x.Mul(e.x, inv)
   217  	e.x.Mod(e.x, P)
   218  
   219  	e.y.Mul(a.y, inv)
   220  	e.y.Mod(e.y, P)
   221  
   222  	pool.Put(t)
   223  	pool.Put(t2)
   224  	pool.Put(inv)
   225  
   226  	return e
   227  }
   228  
   229  func (e *gfP2) Real() *big.Int {
   230  	return e.x
   231  }
   232  
   233  func (e *gfP2) Imag() *big.Int {
   234  	return e.y
   235  }