github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/cloudflare/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 //</624342625641566208> 11 12 package bn256 13 14 import ( 15 "math/big" 16 ) 17 18 //Twistpoint在gf(p²)上实现椭圆曲线y²=x³+3/ξ。点是 19 //以雅可比形式保存,有效时t=z²。G组是一组 20 //n——该曲线在gf(p²)上的扭转点(其中n=阶数) 21 type twistPoint struct { 22 x, y, z, t gfP2 23 } 24 25 var twistB = &gfP2{ 26 gfP{0x38e7ecccd1dcff67, 0x65f0b37d93ce0d3e, 0xd749d0dd22ac00aa, 0x0141b9ce4a688d4d}, 27 gfP{0x3bf938e377b802a8, 0x020b1b273633535d, 0x26b7edf049755260, 0x2514c6324384a86d}, 28 } 29 30 //TwistGen是G组的发生器。 31 var twistGen = &twistPoint{ 32 gfP2{ 33 gfP{0xafb4737da84c6140, 0x6043dd5a5802d8c4, 0x09e950fc52a02f86, 0x14fef0833aea7b6b}, 34 gfP{0x8e83b5d102bc2026, 0xdceb1935497b0172, 0xfbb8264797811adf, 0x19573841af96503b}, 35 }, 36 gfP2{ 37 gfP{0x64095b56c71856ee, 0xdc57f922327d3cbb, 0x55f935be33351076, 0x0da4a0e693fd6482}, 38 gfP{0x619dfa9d886be9f6, 0xfe7fd297f59e9b78, 0xff9e1a62231b7dfe, 0x28fd7eebae9e4206}, 39 }, 40 gfP2{*newGFp(0), *newGFp(1)}, 41 gfP2{*newGFp(0), *newGFp(1)}, 42 } 43 44 func (c *twistPoint) String() string { 45 c.MakeAffine() 46 x, y := gfP2Decode(&c.x), gfP2Decode(&c.y) 47 return "(" + x.String() + ", " + y.String() + ")" 48 } 49 50 func (c *twistPoint) Set(a *twistPoint) { 51 c.x.Set(&a.x) 52 c.y.Set(&a.y) 53 c.z.Set(&a.z) 54 c.t.Set(&a.t) 55 } 56 57 //is on curve返回真的iff c在曲线上。 58 func (c *twistPoint) IsOnCurve() bool { 59 c.MakeAffine() 60 if c.IsInfinity() { 61 return true 62 } 63 64 y2, x3 := &gfP2{}, &gfP2{} 65 y2.Square(&c.y) 66 x3.Square(&c.x).Mul(x3, &c.x).Add(x3, twistB) 67 68 if *y2 != *x3 { 69 return false 70 } 71 cneg := &twistPoint{} 72 cneg.Mul(c, Order) 73 return cneg.z.IsZero() 74 } 75 76 func (c *twistPoint) SetInfinity() { 77 c.x.SetZero() 78 c.y.SetOne() 79 c.z.SetZero() 80 c.t.SetZero() 81 } 82 83 func (c *twistPoint) IsInfinity() bool { 84 return c.z.IsZero() 85 } 86 87 func (c *twistPoint) Add(a, b *twistPoint) { 88 //有关其他注释,请参见curve.go中的相同函数。 89 90 if a.IsInfinity() { 91 c.Set(b) 92 return 93 } 94 if b.IsInfinity() { 95 c.Set(a) 96 return 97 } 98 99 //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 100 z12 := (&gfP2{}).Square(&a.z) 101 z22 := (&gfP2{}).Square(&b.z) 102 u1 := (&gfP2{}).Mul(&a.x, z22) 103 u2 := (&gfP2{}).Mul(&b.x, z12) 104 105 t := (&gfP2{}).Mul(&b.z, z22) 106 s1 := (&gfP2{}).Mul(&a.y, t) 107 108 t.Mul(&a.z, z12) 109 s2 := (&gfP2{}).Mul(&b.y, t) 110 111 h := (&gfP2{}).Sub(u2, u1) 112 xEqual := h.IsZero() 113 114 t.Add(h, h) 115 i := (&gfP2{}).Square(t) 116 j := (&gfP2{}).Mul(h, i) 117 118 t.Sub(s2, s1) 119 yEqual := t.IsZero() 120 if xEqual && yEqual { 121 c.Double(a) 122 return 123 } 124 r := (&gfP2{}).Add(t, t) 125 126 v := (&gfP2{}).Mul(u1, i) 127 128 t4 := (&gfP2{}).Square(r) 129 t.Add(v, v) 130 t6 := (&gfP2{}).Sub(t4, j) 131 c.x.Sub(t6, t) 132 133 t.Sub(v, &c.x) //T7 134 t4.Mul(s1, j) //T8 135 t6.Add(t4, t4) //T9 136 t4.Mul(r, t) //T10 137 c.y.Sub(t4, t6) 138 139 t.Add(&a.z, &b.z) //T11 140 t4.Square(t) //T12 141 t.Sub(t4, z12) //T13 142 t4.Sub(t, z22) //T14 143 c.z.Mul(t4, h) 144 } 145 146 func (c *twistPoint) Double(a *twistPoint) { 147 //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3 148 A := (&gfP2{}).Square(&a.x) 149 B := (&gfP2{}).Square(&a.y) 150 C := (&gfP2{}).Square(B) 151 152 t := (&gfP2{}).Add(&a.x, B) 153 t2 := (&gfP2{}).Square(t) 154 t.Sub(t2, A) 155 t2.Sub(t, C) 156 d := (&gfP2{}).Add(t2, t2) 157 t.Add(A, A) 158 e := (&gfP2{}).Add(t, A) 159 f := (&gfP2{}).Square(e) 160 161 t.Add(d, d) 162 c.x.Sub(f, t) 163 164 t.Add(C, C) 165 t2.Add(t, t) 166 t.Add(t2, t2) 167 c.y.Sub(d, &c.x) 168 t2.Mul(e, &c.y) 169 c.y.Sub(t2, t) 170 171 t.Mul(&a.y, &a.z) 172 c.z.Add(t, t) 173 } 174 175 func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) { 176 sum, t := &twistPoint{}, &twistPoint{} 177 178 for i := scalar.BitLen(); i >= 0; i-- { 179 t.Double(sum) 180 if scalar.Bit(i) != 0 { 181 sum.Add(t, a) 182 } else { 183 sum.Set(t) 184 } 185 } 186 187 c.Set(sum) 188 } 189 190 func (c *twistPoint) MakeAffine() { 191 if c.z.IsOne() { 192 return 193 } else if c.z.IsZero() { 194 c.x.SetZero() 195 c.y.SetOne() 196 c.t.SetZero() 197 return 198 } 199 200 zInv := (&gfP2{}).Invert(&c.z) 201 t := (&gfP2{}).Mul(&c.y, zInv) 202 zInv2 := (&gfP2{}).Square(zInv) 203 c.y.Mul(t, zInv2) 204 t.Mul(&c.x, zInv2) 205 c.x.Set(t) 206 c.z.SetOne() 207 c.t.SetOne() 208 } 209 210 func (c *twistPoint) Neg(a *twistPoint) { 211 c.x.Set(&a.x) 212 c.y.Neg(&a.y) 213 c.z.Set(&a.z) 214 c.t.SetZero() 215 } 216