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