github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/google/twist.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  //</624342626493009920>
    11  
    12  //版权所有2012 Go作者。版权所有。
    13  //此源代码的使用受BSD样式的控制
    14  //可以在许可文件中找到的许可证。
    15  
    16  package bn256
    17  
    18  import (
    19  	"math/big"
    20  )
    21  
    22  //Twistpoint在gf(p²)上实现椭圆曲线y²=x³+3/ξ。点是
    23  //以雅可比形式保存,有效时t=z²。G组是一组
    24  //n——该曲线在gf(p²)上的扭转点(其中n=阶数)
    25  type twistPoint struct {
    26  	x, y, z, t *gfP2
    27  }
    28  
    29  var twistB = &gfP2{
    30  	bigFromBase10("266929791119991161246907387137283842545076965332900288569378510910307636690"),
    31  	bigFromBase10("19485874751759354771024239261021720505790618469301721065564631296452457478373"),
    32  }
    33  
    34  //TwistGen是G组的发生器。
    35  var twistGen = &twistPoint{
    36  	&gfP2{
    37  		bigFromBase10("11559732032986387107991004021392285783925812861821192530917403151452391805634"),
    38  		bigFromBase10("10857046999023057135944570762232829481370756359578518086990519993285655852781"),
    39  	},
    40  	&gfP2{
    41  		bigFromBase10("4082367875863433681332203403145435568316851327593401208105741076214120093531"),
    42  		bigFromBase10("8495653923123431417604973247489272438418190587263600148770280649306958101930"),
    43  	},
    44  	&gfP2{
    45  		bigFromBase10("0"),
    46  		bigFromBase10("1"),
    47  	},
    48  	&gfP2{
    49  		bigFromBase10("0"),
    50  		bigFromBase10("1"),
    51  	},
    52  }
    53  
    54  func newTwistPoint(pool *bnPool) *twistPoint {
    55  	return &twistPoint{
    56  		newGFp2(pool),
    57  		newGFp2(pool),
    58  		newGFp2(pool),
    59  		newGFp2(pool),
    60  	}
    61  }
    62  
    63  func (c *twistPoint) String() string {
    64  	return "(" + c.x.String() + ", " + c.y.String() + ", " + c.z.String() + ")"
    65  }
    66  
    67  func (c *twistPoint) Put(pool *bnPool) {
    68  	c.x.Put(pool)
    69  	c.y.Put(pool)
    70  	c.z.Put(pool)
    71  	c.t.Put(pool)
    72  }
    73  
    74  func (c *twistPoint) Set(a *twistPoint) {
    75  	c.x.Set(a.x)
    76  	c.y.Set(a.y)
    77  	c.z.Set(a.z)
    78  	c.t.Set(a.t)
    79  }
    80  
    81  //is on curve返回真正的iff c在曲线上,其中c必须是仿射形式。
    82  func (c *twistPoint) IsOnCurve() bool {
    83  	pool := new(bnPool)
    84  	yy := newGFp2(pool).Square(c.y, pool)
    85  	xxx := newGFp2(pool).Square(c.x, pool)
    86  	xxx.Mul(xxx, c.x, pool)
    87  	yy.Sub(yy, xxx)
    88  	yy.Sub(yy, twistB)
    89  	yy.Minimal()
    90  
    91  	if yy.x.Sign() != 0 || yy.y.Sign() != 0 {
    92  		return false
    93  	}
    94  	cneg := newTwistPoint(pool)
    95  	cneg.Mul(c, Order, pool)
    96  	return cneg.z.IsZero()
    97  }
    98  
    99  func (c *twistPoint) SetInfinity() {
   100  	c.z.SetZero()
   101  }
   102  
   103  func (c *twistPoint) IsInfinity() bool {
   104  	return c.z.IsZero()
   105  }
   106  
   107  func (c *twistPoint) Add(a, b *twistPoint, pool *bnPool) {
   108  //有关其他注释,请参见curve.go中的相同函数。
   109  
   110  	if a.IsInfinity() {
   111  		c.Set(b)
   112  		return
   113  	}
   114  	if b.IsInfinity() {
   115  		c.Set(a)
   116  		return
   117  	}
   118  
   119  //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3
   120  	z1z1 := newGFp2(pool).Square(a.z, pool)
   121  	z2z2 := newGFp2(pool).Square(b.z, pool)
   122  	u1 := newGFp2(pool).Mul(a.x, z2z2, pool)
   123  	u2 := newGFp2(pool).Mul(b.x, z1z1, pool)
   124  
   125  	t := newGFp2(pool).Mul(b.z, z2z2, pool)
   126  	s1 := newGFp2(pool).Mul(a.y, t, pool)
   127  
   128  	t.Mul(a.z, z1z1, pool)
   129  	s2 := newGFp2(pool).Mul(b.y, t, pool)
   130  
   131  	h := newGFp2(pool).Sub(u2, u1)
   132  	xEqual := h.IsZero()
   133  
   134  	t.Add(h, h)
   135  	i := newGFp2(pool).Square(t, pool)
   136  	j := newGFp2(pool).Mul(h, i, pool)
   137  
   138  	t.Sub(s2, s1)
   139  	yEqual := t.IsZero()
   140  	if xEqual && yEqual {
   141  		c.Double(a, pool)
   142  		return
   143  	}
   144  	r := newGFp2(pool).Add(t, t)
   145  
   146  	v := newGFp2(pool).Mul(u1, i, pool)
   147  
   148  	t4 := newGFp2(pool).Square(r, pool)
   149  	t.Add(v, v)
   150  	t6 := newGFp2(pool).Sub(t4, j)
   151  	c.x.Sub(t6, t)
   152  
   153  t.Sub(v, c.x)       //T7
   154  t4.Mul(s1, j, pool) //T8
   155  t6.Add(t4, t4)      //T9
   156  t4.Mul(r, t, pool)  //T10
   157  	c.y.Sub(t4, t6)
   158  
   159  t.Add(a.z, b.z)    //T11
   160  t4.Square(t, pool) //T12
   161  t.Sub(t4, z1z1)    //T13
   162  t4.Sub(t, z2z2)    //T14
   163  	c.z.Mul(t4, h, pool)
   164  
   165  	z1z1.Put(pool)
   166  	z2z2.Put(pool)
   167  	u1.Put(pool)
   168  	u2.Put(pool)
   169  	t.Put(pool)
   170  	s1.Put(pool)
   171  	s2.Put(pool)
   172  	h.Put(pool)
   173  	i.Put(pool)
   174  	j.Put(pool)
   175  	r.Put(pool)
   176  	v.Put(pool)
   177  	t4.Put(pool)
   178  	t6.Put(pool)
   179  }
   180  
   181  func (c *twistPoint) Double(a *twistPoint, pool *bnPool) {
   182  //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3
   183  	A := newGFp2(pool).Square(a.x, pool)
   184  	B := newGFp2(pool).Square(a.y, pool)
   185  	C_ := newGFp2(pool).Square(B, pool)
   186  
   187  	t := newGFp2(pool).Add(a.x, B)
   188  	t2 := newGFp2(pool).Square(t, pool)
   189  	t.Sub(t2, A)
   190  	t2.Sub(t, C_)
   191  	d := newGFp2(pool).Add(t2, t2)
   192  	t.Add(A, A)
   193  	e := newGFp2(pool).Add(t, A)
   194  	f := newGFp2(pool).Square(e, pool)
   195  
   196  	t.Add(d, d)
   197  	c.x.Sub(f, t)
   198  
   199  	t.Add(C_, C_)
   200  	t2.Add(t, t)
   201  	t.Add(t2, t2)
   202  	c.y.Sub(d, c.x)
   203  	t2.Mul(e, c.y, pool)
   204  	c.y.Sub(t2, t)
   205  
   206  	t.Mul(a.y, a.z, pool)
   207  	c.z.Add(t, t)
   208  
   209  	A.Put(pool)
   210  	B.Put(pool)
   211  	C_.Put(pool)
   212  	t.Put(pool)
   213  	t2.Put(pool)
   214  	d.Put(pool)
   215  	e.Put(pool)
   216  	f.Put(pool)
   217  }
   218  
   219  func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int, pool *bnPool) *twistPoint {
   220  	sum := newTwistPoint(pool)
   221  	sum.SetInfinity()
   222  	t := newTwistPoint(pool)
   223  
   224  	for i := scalar.BitLen(); i >= 0; i-- {
   225  		t.Double(sum, pool)
   226  		if scalar.Bit(i) != 0 {
   227  			sum.Add(t, a, pool)
   228  		} else {
   229  			sum.Set(t)
   230  		}
   231  	}
   232  
   233  	c.Set(sum)
   234  	sum.Put(pool)
   235  	t.Put(pool)
   236  	return c
   237  }
   238  
   239  //makeaffine将c转换为affine形式并返回c。如果c是∞,则它设置
   240  //C到0:1:0。
   241  func (c *twistPoint) MakeAffine(pool *bnPool) *twistPoint {
   242  	if c.z.IsOne() {
   243  		return c
   244  	}
   245  	if c.IsInfinity() {
   246  		c.x.SetZero()
   247  		c.y.SetOne()
   248  		c.z.SetZero()
   249  		c.t.SetZero()
   250  		return c
   251  	}
   252  	zInv := newGFp2(pool).Invert(c.z, pool)
   253  	t := newGFp2(pool).Mul(c.y, zInv, pool)
   254  	zInv2 := newGFp2(pool).Square(zInv, pool)
   255  	c.y.Mul(t, zInv2, pool)
   256  	t.Mul(c.x, zInv2, pool)
   257  	c.x.Set(t)
   258  	c.z.SetOne()
   259  	c.t.SetOne()
   260  
   261  	zInv.Put(pool)
   262  	t.Put(pool)
   263  	zInv2.Put(pool)
   264  
   265  	return c
   266  }
   267  
   268  func (c *twistPoint) Negative(a *twistPoint, pool *bnPool) {
   269  	c.x.Set(a.x)
   270  	c.y.SetZero()
   271  	c.y.Sub(c.y, a.y)
   272  	c.z.Set(a.z)
   273  	c.t.SetZero()
   274  }
   275