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