github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/google/gfp12.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  //</624342626132299776>
    11  
    12  //版权所有2012 Go作者。版权所有。
    13  //此源代码的使用受BSD样式的控制
    14  //可以在许可文件中找到的许可证。
    15  
    16  package bn256
    17  
    18  //有关所用算法的详细信息,请参阅
    19  //配对友好字段,Devegili等人
    20  //http://eprint.iacr.org/2006/471.pdf。
    21  
    22  import (
    23  	"math/big"
    24  )
    25  
    26  //gfp12将大小为p的字段实现为gfp6的二次扩展
    27  //其中ω=TA.
    28  type gfP12 struct {
    29  x, y *gfP6 //值为xω+y
    30  }
    31  
    32  func newGFp12(pool *bnPool) *gfP12 {
    33  	return &gfP12{newGFp6(pool), newGFp6(pool)}
    34  }
    35  
    36  func (e *gfP12) String() string {
    37  	return "(" + e.x.String() + "," + e.y.String() + ")"
    38  }
    39  
    40  func (e *gfP12) Put(pool *bnPool) {
    41  	e.x.Put(pool)
    42  	e.y.Put(pool)
    43  }
    44  
    45  func (e *gfP12) Set(a *gfP12) *gfP12 {
    46  	e.x.Set(a.x)
    47  	e.y.Set(a.y)
    48  	return e
    49  }
    50  
    51  func (e *gfP12) SetZero() *gfP12 {
    52  	e.x.SetZero()
    53  	e.y.SetZero()
    54  	return e
    55  }
    56  
    57  func (e *gfP12) SetOne() *gfP12 {
    58  	e.x.SetZero()
    59  	e.y.SetOne()
    60  	return e
    61  }
    62  
    63  func (e *gfP12) Minimal() {
    64  	e.x.Minimal()
    65  	e.y.Minimal()
    66  }
    67  
    68  func (e *gfP12) IsZero() bool {
    69  	e.Minimal()
    70  	return e.x.IsZero() && e.y.IsZero()
    71  }
    72  
    73  func (e *gfP12) IsOne() bool {
    74  	e.Minimal()
    75  	return e.x.IsZero() && e.y.IsOne()
    76  }
    77  
    78  func (e *gfP12) Conjugate(a *gfP12) *gfP12 {
    79  	e.x.Negative(a.x)
    80  	e.y.Set(a.y)
    81  	return a
    82  }
    83  
    84  func (e *gfP12) Negative(a *gfP12) *gfP12 {
    85  	e.x.Negative(a.x)
    86  	e.y.Negative(a.y)
    87  	return e
    88  }
    89  
    90  //弗罗贝尼乌斯计算(xω+y)^p=x^pω·ξ^((p-1)/6)+y^p
    91  func (e *gfP12) Frobenius(a *gfP12, pool *bnPool) *gfP12 {
    92  	e.x.Frobenius(a.x, pool)
    93  	e.y.Frobenius(a.y, pool)
    94  	e.x.MulScalar(e.x, xiToPMinus1Over6, pool)
    95  	return e
    96  }
    97  
    98  //frobiniusp2计算(xω+y)^p²=x^p²ω·ξ^((p²-1)/6)+y^p²
    99  func (e *gfP12) FrobeniusP2(a *gfP12, pool *bnPool) *gfP12 {
   100  	e.x.FrobeniusP2(a.x)
   101  	e.x.MulGFP(e.x, xiToPSquaredMinus1Over6)
   102  	e.y.FrobeniusP2(a.y)
   103  	return e
   104  }
   105  
   106  func (e *gfP12) Add(a, b *gfP12) *gfP12 {
   107  	e.x.Add(a.x, b.x)
   108  	e.y.Add(a.y, b.y)
   109  	return e
   110  }
   111  
   112  func (e *gfP12) Sub(a, b *gfP12) *gfP12 {
   113  	e.x.Sub(a.x, b.x)
   114  	e.y.Sub(a.y, b.y)
   115  	return e
   116  }
   117  
   118  func (e *gfP12) Mul(a, b *gfP12, pool *bnPool) *gfP12 {
   119  	tx := newGFp6(pool)
   120  	tx.Mul(a.x, b.y, pool)
   121  	t := newGFp6(pool)
   122  	t.Mul(b.x, a.y, pool)
   123  	tx.Add(tx, t)
   124  
   125  	ty := newGFp6(pool)
   126  	ty.Mul(a.y, b.y, pool)
   127  	t.Mul(a.x, b.x, pool)
   128  	t.MulTau(t, pool)
   129  	e.y.Add(ty, t)
   130  	e.x.Set(tx)
   131  
   132  	tx.Put(pool)
   133  	ty.Put(pool)
   134  	t.Put(pool)
   135  	return e
   136  }
   137  
   138  func (e *gfP12) MulScalar(a *gfP12, b *gfP6, pool *bnPool) *gfP12 {
   139  	e.x.Mul(e.x, b, pool)
   140  	e.y.Mul(e.y, b, pool)
   141  	return e
   142  }
   143  
   144  func (c *gfP12) Exp(a *gfP12, power *big.Int, pool *bnPool) *gfP12 {
   145  	sum := newGFp12(pool)
   146  	sum.SetOne()
   147  	t := newGFp12(pool)
   148  
   149  	for i := power.BitLen() - 1; i >= 0; i-- {
   150  		t.Square(sum, pool)
   151  		if power.Bit(i) != 0 {
   152  			sum.Mul(t, a, pool)
   153  		} else {
   154  			sum.Set(t)
   155  		}
   156  	}
   157  
   158  	c.Set(sum)
   159  
   160  	sum.Put(pool)
   161  	t.Put(pool)
   162  
   163  	return c
   164  }
   165  
   166  func (e *gfP12) Square(a *gfP12, pool *bnPool) *gfP12 {
   167  //复平方算法
   168  	v0 := newGFp6(pool)
   169  	v0.Mul(a.x, a.y, pool)
   170  
   171  	t := newGFp6(pool)
   172  	t.MulTau(a.x, pool)
   173  	t.Add(a.y, t)
   174  	ty := newGFp6(pool)
   175  	ty.Add(a.x, a.y)
   176  	ty.Mul(ty, t, pool)
   177  	ty.Sub(ty, v0)
   178  	t.MulTau(v0, pool)
   179  	ty.Sub(ty, t)
   180  
   181  	e.y.Set(ty)
   182  	e.x.Double(v0)
   183  
   184  	v0.Put(pool)
   185  	t.Put(pool)
   186  	ty.Put(pool)
   187  
   188  	return e
   189  }
   190  
   191  func (e *gfP12) Invert(a *gfP12, pool *bnPool) *gfP12 {
   192  //见“实现密码配对”,M.Scott,第3.2节。
   193  //ftp://136.206.11.249/pub/crypto/pairing.pdf文件
   194  	t1 := newGFp6(pool)
   195  	t2 := newGFp6(pool)
   196  
   197  	t1.Square(a.x, pool)
   198  	t2.Square(a.y, pool)
   199  	t1.MulTau(t1, pool)
   200  	t1.Sub(t2, t1)
   201  	t2.Invert(t1, pool)
   202  
   203  	e.x.Negative(a.x)
   204  	e.y.Set(a.y)
   205  	e.MulScalar(e, t2, pool)
   206  
   207  	t1.Put(pool)
   208  	t2.Put(pool)
   209  
   210  	return e
   211  }
   212