github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/google/gfp6.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  //gfp6将大小为p_的字段作为gfp2的三次扩展,其中τ3=ξ
    24  //和Zi= i + 9。
    25  type gfP6 struct {
    26  x, y, z *gfP2 //值为xτ2+yτ+z
    27  }
    28  
    29  func newGFp6(pool *bnPool) *gfP6 {
    30  	return &gfP6{newGFp2(pool), newGFp2(pool), newGFp2(pool)}
    31  }
    32  
    33  func (e *gfP6) String() string {
    34  	return "(" + e.x.String() + "," + e.y.String() + "," + e.z.String() + ")"
    35  }
    36  
    37  func (e *gfP6) Put(pool *bnPool) {
    38  	e.x.Put(pool)
    39  	e.y.Put(pool)
    40  	e.z.Put(pool)
    41  }
    42  
    43  func (e *gfP6) Set(a *gfP6) *gfP6 {
    44  	e.x.Set(a.x)
    45  	e.y.Set(a.y)
    46  	e.z.Set(a.z)
    47  	return e
    48  }
    49  
    50  func (e *gfP6) SetZero() *gfP6 {
    51  	e.x.SetZero()
    52  	e.y.SetZero()
    53  	e.z.SetZero()
    54  	return e
    55  }
    56  
    57  func (e *gfP6) SetOne() *gfP6 {
    58  	e.x.SetZero()
    59  	e.y.SetZero()
    60  	e.z.SetOne()
    61  	return e
    62  }
    63  
    64  func (e *gfP6) Minimal() {
    65  	e.x.Minimal()
    66  	e.y.Minimal()
    67  	e.z.Minimal()
    68  }
    69  
    70  func (e *gfP6) IsZero() bool {
    71  	return e.x.IsZero() && e.y.IsZero() && e.z.IsZero()
    72  }
    73  
    74  func (e *gfP6) IsOne() bool {
    75  	return e.x.IsZero() && e.y.IsZero() && e.z.IsOne()
    76  }
    77  
    78  func (e *gfP6) Negative(a *gfP6) *gfP6 {
    79  	e.x.Negative(a.x)
    80  	e.y.Negative(a.y)
    81  	e.z.Negative(a.z)
    82  	return e
    83  }
    84  
    85  func (e *gfP6) Frobenius(a *gfP6, pool *bnPool) *gfP6 {
    86  	e.x.Conjugate(a.x)
    87  	e.y.Conjugate(a.y)
    88  	e.z.Conjugate(a.z)
    89  
    90  	e.x.Mul(e.x, xiTo2PMinus2Over3, pool)
    91  	e.y.Mul(e.y, xiToPMinus1Over3, pool)
    92  	return e
    93  }
    94  
    95  //Frobeniusp2计算(xτ2+yτ+z)^(p²)=xτ^(2p²)+yτ^(p²)+z
    96  func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 {
    97  //τ^(2p平方)=ττ^(2p平方-2)=τξ^((2p平方-2)/3)
    98  	e.x.MulScalar(a.x, xiTo2PSquaredMinus2Over3)
    99  //τ^(p²)=τ^(p²-1)=τξ^((p²-1)/3)
   100  	e.y.MulScalar(a.y, xiToPSquaredMinus1Over3)
   101  	e.z.Set(a.z)
   102  	return e
   103  }
   104  
   105  func (e *gfP6) Add(a, b *gfP6) *gfP6 {
   106  	e.x.Add(a.x, b.x)
   107  	e.y.Add(a.y, b.y)
   108  	e.z.Add(a.z, b.z)
   109  	return e
   110  }
   111  
   112  func (e *gfP6) Sub(a, b *gfP6) *gfP6 {
   113  	e.x.Sub(a.x, b.x)
   114  	e.y.Sub(a.y, b.y)
   115  	e.z.Sub(a.z, b.z)
   116  	return e
   117  }
   118  
   119  func (e *gfP6) Double(a *gfP6) *gfP6 {
   120  	e.x.Double(a.x)
   121  	e.y.Double(a.y)
   122  	e.z.Double(a.z)
   123  	return e
   124  }
   125  
   126  func (e *gfP6) Mul(a, b *gfP6, pool *bnPool) *gfP6 {
   127  //“对友好字段的乘法和平方”
   128  //第4节,Karatsuba方法。
   129  //http://eprint.iacr.org/2006/471.pdf
   130  
   131  	v0 := newGFp2(pool)
   132  	v0.Mul(a.z, b.z, pool)
   133  	v1 := newGFp2(pool)
   134  	v1.Mul(a.y, b.y, pool)
   135  	v2 := newGFp2(pool)
   136  	v2.Mul(a.x, b.x, pool)
   137  
   138  	t0 := newGFp2(pool)
   139  	t0.Add(a.x, a.y)
   140  	t1 := newGFp2(pool)
   141  	t1.Add(b.x, b.y)
   142  	tz := newGFp2(pool)
   143  	tz.Mul(t0, t1, pool)
   144  
   145  	tz.Sub(tz, v1)
   146  	tz.Sub(tz, v2)
   147  	tz.MulXi(tz, pool)
   148  	tz.Add(tz, v0)
   149  
   150  	t0.Add(a.y, a.z)
   151  	t1.Add(b.y, b.z)
   152  	ty := newGFp2(pool)
   153  	ty.Mul(t0, t1, pool)
   154  	ty.Sub(ty, v0)
   155  	ty.Sub(ty, v1)
   156  	t0.MulXi(v2, pool)
   157  	ty.Add(ty, t0)
   158  
   159  	t0.Add(a.x, a.z)
   160  	t1.Add(b.x, b.z)
   161  	tx := newGFp2(pool)
   162  	tx.Mul(t0, t1, pool)
   163  	tx.Sub(tx, v0)
   164  	tx.Add(tx, v1)
   165  	tx.Sub(tx, v2)
   166  
   167  	e.x.Set(tx)
   168  	e.y.Set(ty)
   169  	e.z.Set(tz)
   170  
   171  	t0.Put(pool)
   172  	t1.Put(pool)
   173  	tx.Put(pool)
   174  	ty.Put(pool)
   175  	tz.Put(pool)
   176  	v0.Put(pool)
   177  	v1.Put(pool)
   178  	v2.Put(pool)
   179  	return e
   180  }
   181  
   182  func (e *gfP6) MulScalar(a *gfP6, b *gfP2, pool *bnPool) *gfP6 {
   183  	e.x.Mul(a.x, b, pool)
   184  	e.y.Mul(a.y, b, pool)
   185  	e.z.Mul(a.z, b, pool)
   186  	return e
   187  }
   188  
   189  func (e *gfP6) MulGFP(a *gfP6, b *big.Int) *gfP6 {
   190  	e.x.MulScalar(a.x, b)
   191  	e.y.MulScalar(a.y, b)
   192  	e.z.MulScalar(a.z, b)
   193  	return e
   194  }
   195  
   196  //multau计算τ·(aτ2+bτ+c)=bτ2+cτ+aξ
   197  func (e *gfP6) MulTau(a *gfP6, pool *bnPool) {
   198  	tz := newGFp2(pool)
   199  	tz.MulXi(a.x, pool)
   200  	ty := newGFp2(pool)
   201  	ty.Set(a.y)
   202  	e.y.Set(a.z)
   203  	e.x.Set(ty)
   204  	e.z.Set(tz)
   205  	tz.Put(pool)
   206  	ty.Put(pool)
   207  }
   208  
   209  func (e *gfP6) Square(a *gfP6, pool *bnPool) *gfP6 {
   210  	v0 := newGFp2(pool).Square(a.z, pool)
   211  	v1 := newGFp2(pool).Square(a.y, pool)
   212  	v2 := newGFp2(pool).Square(a.x, pool)
   213  
   214  	c0 := newGFp2(pool).Add(a.x, a.y)
   215  	c0.Square(c0, pool)
   216  	c0.Sub(c0, v1)
   217  	c0.Sub(c0, v2)
   218  	c0.MulXi(c0, pool)
   219  	c0.Add(c0, v0)
   220  
   221  	c1 := newGFp2(pool).Add(a.y, a.z)
   222  	c1.Square(c1, pool)
   223  	c1.Sub(c1, v0)
   224  	c1.Sub(c1, v1)
   225  	xiV2 := newGFp2(pool).MulXi(v2, pool)
   226  	c1.Add(c1, xiV2)
   227  
   228  	c2 := newGFp2(pool).Add(a.x, a.z)
   229  	c2.Square(c2, pool)
   230  	c2.Sub(c2, v0)
   231  	c2.Add(c2, v1)
   232  	c2.Sub(c2, v2)
   233  
   234  	e.x.Set(c2)
   235  	e.y.Set(c1)
   236  	e.z.Set(c0)
   237  
   238  	v0.Put(pool)
   239  	v1.Put(pool)
   240  	v2.Put(pool)
   241  	c0.Put(pool)
   242  	c1.Put(pool)
   243  	c2.Put(pool)
   244  	xiV2.Put(pool)
   245  
   246  	return e
   247  }
   248  
   249  func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 {
   250  //见“实现密码配对”,M.Scott,第3.2节。
   251  //ftp://136.206.11.249/pub/crypto/pairing.pdf文件
   252  
   253  //这里我们可以简单解释一下它是如何工作的:让j是
   254  //单位为gf(p平方),因此1+j+j平方=0。
   255  //则(xτ2+yτ+z)(xjτ2+yjτ+z)(xjτ2+yjτ+z)
   256  //=(xτ2+yτ+z)(cτ2+bτ+a)
   257  //=(X酴酴酴+Y酴酴酴酴+Z酴-3酴x y z)=F是基场(范数)的元素。
   258  //
   259  //另一方面(xjτ2+yjτ+z)(xjτ2+yjτ+z)
   260  //=τ2(y 2-ξxz)+τ(ξx 2-y z)+(z 2-ξxy)
   261  //
   262  //所以这就是为什么a=(z-ξxy),b=(ξx-y z),c=(y-ξxz)
   263  	t1 := newGFp2(pool)
   264  
   265  	A := newGFp2(pool)
   266  	A.Square(a.z, pool)
   267  	t1.Mul(a.x, a.y, pool)
   268  	t1.MulXi(t1, pool)
   269  	A.Sub(A, t1)
   270  
   271  	B := newGFp2(pool)
   272  	B.Square(a.x, pool)
   273  	B.MulXi(B, pool)
   274  	t1.Mul(a.y, a.z, pool)
   275  	B.Sub(B, t1)
   276  
   277  	C_ := newGFp2(pool)
   278  	C_.Square(a.y, pool)
   279  	t1.Mul(a.x, a.z, pool)
   280  	C_.Sub(C_, t1)
   281  
   282  	F := newGFp2(pool)
   283  	F.Mul(C_, a.y, pool)
   284  	F.MulXi(F, pool)
   285  	t1.Mul(A, a.z, pool)
   286  	F.Add(F, t1)
   287  	t1.Mul(B, a.x, pool)
   288  	t1.MulXi(t1, pool)
   289  	F.Add(F, t1)
   290  
   291  	F.Invert(F, pool)
   292  
   293  	e.x.Mul(C_, F, pool)
   294  	e.y.Mul(B, F, pool)
   295  	e.z.Mul(A, F, pool)
   296  
   297  	t1.Put(pool)
   298  	A.Put(pool)
   299  	B.Put(pool)
   300  	C_.Put(pool)
   301  	F.Put(pool)
   302  
   303  	return e
   304  }