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