github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/bn256/cloudflare/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  package bn256
    10  
    11  //有关所用算法的详细信息,请参阅
    12  //配对友好字段,Devegili等人
    13  //http://eprint.iacr.org/2006/471.pdf。
    14  
    15  //gfp6将大小为p_的字段作为gfp2的三次扩展,其中τ3=ξ
    16  //和Zi= i + 3。
    17  type gfP6 struct {
    18  x, y, z gfP2 //值为xτ2+yτ+z
    19  }
    20  
    21  func (e *gfP6) String() string {
    22  	return "(" + e.x.String() + ", " + e.y.String() + ", " + e.z.String() + ")"
    23  }
    24  
    25  func (e *gfP6) Set(a *gfP6) *gfP6 {
    26  	e.x.Set(&a.x)
    27  	e.y.Set(&a.y)
    28  	e.z.Set(&a.z)
    29  	return e
    30  }
    31  
    32  func (e *gfP6) SetZero() *gfP6 {
    33  	e.x.SetZero()
    34  	e.y.SetZero()
    35  	e.z.SetZero()
    36  	return e
    37  }
    38  
    39  func (e *gfP6) SetOne() *gfP6 {
    40  	e.x.SetZero()
    41  	e.y.SetZero()
    42  	e.z.SetOne()
    43  	return e
    44  }
    45  
    46  func (e *gfP6) IsZero() bool {
    47  	return e.x.IsZero() && e.y.IsZero() && e.z.IsZero()
    48  }
    49  
    50  func (e *gfP6) IsOne() bool {
    51  	return e.x.IsZero() && e.y.IsZero() && e.z.IsOne()
    52  }
    53  
    54  func (e *gfP6) Neg(a *gfP6) *gfP6 {
    55  	e.x.Neg(&a.x)
    56  	e.y.Neg(&a.y)
    57  	e.z.Neg(&a.z)
    58  	return e
    59  }
    60  
    61  func (e *gfP6) Frobenius(a *gfP6) *gfP6 {
    62  	e.x.Conjugate(&a.x)
    63  	e.y.Conjugate(&a.y)
    64  	e.z.Conjugate(&a.z)
    65  
    66  	e.x.Mul(&e.x, xiTo2PMinus2Over3)
    67  	e.y.Mul(&e.y, xiToPMinus1Over3)
    68  	return e
    69  }
    70  
    71  //Frobeniusp2计算(xτ2+yτ+z)^(p²)=xτ^(2p²)+yτ^(p²)+z
    72  func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 {
    73  //τ^(2p平方)=ττ^(2p平方-2)=τξ^((2p平方-2)/3)
    74  	e.x.MulScalar(&a.x, xiTo2PSquaredMinus2Over3)
    75  //τ^(p²)=τ^(p²-1)=τξ^((p²-1)/3)
    76  	e.y.MulScalar(&a.y, xiToPSquaredMinus1Over3)
    77  	e.z.Set(&a.z)
    78  	return e
    79  }
    80  
    81  func (e *gfP6) FrobeniusP4(a *gfP6) *gfP6 {
    82  	e.x.MulScalar(&a.x, xiToPSquaredMinus1Over3)
    83  	e.y.MulScalar(&a.y, xiTo2PSquaredMinus2Over3)
    84  	e.z.Set(&a.z)
    85  	return e
    86  }
    87  
    88  func (e *gfP6) Add(a, b *gfP6) *gfP6 {
    89  	e.x.Add(&a.x, &b.x)
    90  	e.y.Add(&a.y, &b.y)
    91  	e.z.Add(&a.z, &b.z)
    92  	return e
    93  }
    94  
    95  func (e *gfP6) Sub(a, b *gfP6) *gfP6 {
    96  	e.x.Sub(&a.x, &b.x)
    97  	e.y.Sub(&a.y, &b.y)
    98  	e.z.Sub(&a.z, &b.z)
    99  	return e
   100  }
   101  
   102  func (e *gfP6) Mul(a, b *gfP6) *gfP6 {
   103  //“对友好字段的乘法和平方”
   104  //第4节,Karatsuba方法。
   105  //http://eprint.iacr.org/2006/471.pdf
   106  	v0 := (&gfP2{}).Mul(&a.z, &b.z)
   107  	v1 := (&gfP2{}).Mul(&a.y, &b.y)
   108  	v2 := (&gfP2{}).Mul(&a.x, &b.x)
   109  
   110  	t0 := (&gfP2{}).Add(&a.x, &a.y)
   111  	t1 := (&gfP2{}).Add(&b.x, &b.y)
   112  	tz := (&gfP2{}).Mul(t0, t1)
   113  	tz.Sub(tz, v1).Sub(tz, v2).MulXi(tz).Add(tz, v0)
   114  
   115  	t0.Add(&a.y, &a.z)
   116  	t1.Add(&b.y, &b.z)
   117  	ty := (&gfP2{}).Mul(t0, t1)
   118  	t0.MulXi(v2)
   119  	ty.Sub(ty, v0).Sub(ty, v1).Add(ty, t0)
   120  
   121  	t0.Add(&a.x, &a.z)
   122  	t1.Add(&b.x, &b.z)
   123  	tx := (&gfP2{}).Mul(t0, t1)
   124  	tx.Sub(tx, v0).Add(tx, v1).Sub(tx, v2)
   125  
   126  	e.x.Set(tx)
   127  	e.y.Set(ty)
   128  	e.z.Set(tz)
   129  	return e
   130  }
   131  
   132  func (e *gfP6) MulScalar(a *gfP6, b *gfP2) *gfP6 {
   133  	e.x.Mul(&a.x, b)
   134  	e.y.Mul(&a.y, b)
   135  	e.z.Mul(&a.z, b)
   136  	return e
   137  }
   138  
   139  func (e *gfP6) MulGFP(a *gfP6, b *gfP) *gfP6 {
   140  	e.x.MulScalar(&a.x, b)
   141  	e.y.MulScalar(&a.y, b)
   142  	e.z.MulScalar(&a.z, b)
   143  	return e
   144  }
   145  
   146  //multau计算τ·(aτ2+bτ+c)=bτ2+cτ+aξ
   147  func (e *gfP6) MulTau(a *gfP6) *gfP6 {
   148  	tz := (&gfP2{}).MulXi(&a.x)
   149  	ty := (&gfP2{}).Set(&a.y)
   150  
   151  	e.y.Set(&a.z)
   152  	e.x.Set(ty)
   153  	e.z.Set(tz)
   154  	return e
   155  }
   156  
   157  func (e *gfP6) Square(a *gfP6) *gfP6 {
   158  	v0 := (&gfP2{}).Square(&a.z)
   159  	v1 := (&gfP2{}).Square(&a.y)
   160  	v2 := (&gfP2{}).Square(&a.x)
   161  
   162  	c0 := (&gfP2{}).Add(&a.x, &a.y)
   163  	c0.Square(c0).Sub(c0, v1).Sub(c0, v2).MulXi(c0).Add(c0, v0)
   164  
   165  	c1 := (&gfP2{}).Add(&a.y, &a.z)
   166  	c1.Square(c1).Sub(c1, v0).Sub(c1, v1)
   167  	xiV2 := (&gfP2{}).MulXi(v2)
   168  	c1.Add(c1, xiV2)
   169  
   170  	c2 := (&gfP2{}).Add(&a.x, &a.z)
   171  	c2.Square(c2).Sub(c2, v0).Add(c2, v1).Sub(c2, v2)
   172  
   173  	e.x.Set(c2)
   174  	e.y.Set(c1)
   175  	e.z.Set(c0)
   176  	return e
   177  }
   178  
   179  func (e *gfP6) Invert(a *gfP6) *gfP6 {
   180  //见“实现密码配对”,M.Scott,第3.2节。
   181  //ftp://136.206.11.249/pub/crypto/pairing.pdf文件
   182  
   183  //这里我们可以简单解释一下它是如何工作的:让j是
   184  //单位为gf(p平方),因此1+j+j平方=0。
   185  //则(xτ2+yτ+z)(xjτ2+yjτ+z)(xjτ2+yjτ+z)
   186  //=(xτ2+yτ+z)(cτ2+bτ+a)
   187  //=(X酴酴酴+Y酴酴酴酴+Z酴-3酴x y z)=F是基场(范数)的元素。
   188  //
   189  //另一方面(xjτ2+yjτ+z)(xjτ2+yjτ+z)
   190  //=τ2(y 2-ξxz)+τ(ξx 2-y z)+(z 2-ξxy)
   191  //
   192  //所以这就是为什么a=(z-ξxy),b=(ξx-y z),c=(y-ξxz)
   193  	t1 := (&gfP2{}).Mul(&a.x, &a.y)
   194  	t1.MulXi(t1)
   195  
   196  	A := (&gfP2{}).Square(&a.z)
   197  	A.Sub(A, t1)
   198  
   199  	B := (&gfP2{}).Square(&a.x)
   200  	B.MulXi(B)
   201  	t1.Mul(&a.y, &a.z)
   202  	B.Sub(B, t1)
   203  
   204  	C := (&gfP2{}).Square(&a.y)
   205  	t1.Mul(&a.x, &a.z)
   206  	C.Sub(C, t1)
   207  
   208  	F := (&gfP2{}).Mul(C, &a.y)
   209  	F.MulXi(F)
   210  	t1.Mul(A, &a.z)
   211  	F.Add(F, t1)
   212  	t1.Mul(B, &a.x).MulXi(t1)
   213  	F.Add(F, t1)
   214  
   215  	F.Invert(F)
   216  
   217  	e.x.Mul(C, F)
   218  	e.y.Mul(B, F)
   219  	e.z.Mul(A, F)
   220  	return e
   221  }