github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/crypto/bn256/cloudflare/curve.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 //</624342624655904768> 11 12 package bn256 13 14 import ( 15 "math/big" 16 ) 17 18 //curvePoint实现椭圆曲线y?=x?+3。积分保存在雅各布文中。 19 //表格,有效时t=z²。g_是gf(p)上该曲线的点集。 20 type curvePoint struct { 21 x, y, z, t gfP 22 } 23 24 var curveB = newGFp(3) 25 26 //曲线发电机是G_的发电机。 27 var curveGen = &curvePoint{ 28 x: *newGFp(1), 29 y: *newGFp(2), 30 z: *newGFp(1), 31 t: *newGFp(1), 32 } 33 34 func (c *curvePoint) String() string { 35 c.MakeAffine() 36 x, y := &gfP{}, &gfP{} 37 montDecode(x, &c.x) 38 montDecode(y, &c.y) 39 return "(" + x.String() + ", " + y.String() + ")" 40 } 41 42 func (c *curvePoint) Set(a *curvePoint) { 43 c.x.Set(&a.x) 44 c.y.Set(&a.y) 45 c.z.Set(&a.z) 46 c.t.Set(&a.t) 47 } 48 49 //is on curve返回真的iff c在曲线上。 50 func (c *curvePoint) IsOnCurve() bool { 51 c.MakeAffine() 52 if c.IsInfinity() { 53 return true 54 } 55 56 y2, x3 := &gfP{}, &gfP{} 57 gfpMul(y2, &c.y, &c.y) 58 gfpMul(x3, &c.x, &c.x) 59 gfpMul(x3, x3, &c.x) 60 gfpAdd(x3, x3, curveB) 61 62 return *y2 == *x3 63 } 64 65 func (c *curvePoint) SetInfinity() { 66 c.x = gfP{0} 67 c.y = *newGFp(1) 68 c.z = gfP{0} 69 c.t = gfP{0} 70 } 71 72 func (c *curvePoint) IsInfinity() bool { 73 return c.z == gfP{0} 74 } 75 76 func (c *curvePoint) Add(a, b *curvePoint) { 77 if a.IsInfinity() { 78 c.Set(b) 79 return 80 } 81 if b.IsInfinity() { 82 c.Set(a) 83 return 84 } 85 86 //见http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/addition/add-2007-bl.op3 87 88 //通过替换a=[x1:y1:z1]和b=[x2:y2:z2]来规范化点。 89 //通过[U1:S1:Z1·Z2]和[U2:S2:Z1·Z2] 90 //式中:U1=x1·z2?、S1=y1·z2?、U1=x2·z1?、S2=y2·z1?? 91 z12, z22 := &gfP{}, &gfP{} 92 gfpMul(z12, &a.z, &a.z) 93 gfpMul(z22, &b.z, &b.z) 94 95 u1, u2 := &gfP{}, &gfP{} 96 gfpMul(u1, &a.x, z22) 97 gfpMul(u2, &b.x, z12) 98 99 t, s1 := &gfP{}, &gfP{} 100 gfpMul(t, &b.z, z22) 101 gfpMul(s1, &a.y, t) 102 103 s2 := &gfP{} 104 gfpMul(t, &a.z, z12) 105 gfpMul(s2, &b.y, t) 106 107 //计算x=(2h)2(s²-u1-u2) 108 //其中s=(s2-s1)/(u2-u1)是线路通过的坡度 109 //(U1、S1)和(U2、S2)。额外因子2h=2(u2-u1)来自下面的z值。 110 //这也是: 111 //4(s2-s1)2-4h 2(u1+u2)=4(s2-s1)2-4h 3-4h 2(2u1) 112 //R=J-2V 113 //以及下面的注释。 114 h := &gfP{} 115 gfpSub(h, u2, u1) 116 xEqual := *h == gfP{0} 117 118 gfpAdd(t, h, h) 119 //I= 4H 120 i := &gfP{} 121 gfpMul(i, t, t) 122 //J= 4H 123 j := &gfP{} 124 gfpMul(j, h, i) 125 126 gfpSub(t, s2, s1) 127 yEqual := *t == gfP{0} 128 if xEqual && yEqual { 129 c.Double(a) 130 return 131 } 132 r := &gfP{} 133 gfpAdd(r, t, t) 134 135 v := &gfP{} 136 gfpMul(v, u1, i) 137 138 //T4=4(S2-S1) 139 t4, t6 := &gfP{}, &gfP{} 140 gfpMul(t4, r, r) 141 gfpAdd(t, v, v) 142 gfpSub(t6, t4, j) 143 144 gfpSub(&c.x, t6, t) 145 146 //设置y=—(2h)³(s1+s*(x/4h²-u1)) 147 //这也是 148 //y=-2·s1·j-(s2-s1)(2x-2i·u1)=r(v-x)-2·s1·j 149 gfpSub(t, v, &c.x) //T7 150 gfpMul(t4, s1, j) //T8 151 gfpAdd(t6, t4, t4) //T9 152 gfpMul(t4, r, t) //T10 153 gfpSub(&c.y, t4, t6) 154 155 //设置z=2(u2-u1)·z1·z2=2h·z1·z2 156 gfpAdd(t, &a.z, &b.z) //T11 157 gfpMul(t4, t, t) //T12 158 gfpSub(t, t4, z12) //T13 159 gfpSub(t4, t, z22) //T14 160 gfpMul(&c.z, t4, h) 161 } 162 163 func (c *curvePoint) Double(a *curvePoint) { 164 //请参阅http://hyper椭圆形.org/efd/g1p/auto-code/shortw/jacobian-0/double/dbl-2009-l.op3 165 A, B, C := &gfP{}, &gfP{}, &gfP{} 166 gfpMul(A, &a.x, &a.x) 167 gfpMul(B, &a.y, &a.y) 168 gfpMul(C, B, B) 169 170 t, t2 := &gfP{}, &gfP{} 171 gfpAdd(t, &a.x, B) 172 gfpMul(t2, t, t) 173 gfpSub(t, t2, A) 174 gfpSub(t2, t, C) 175 176 d, e, f := &gfP{}, &gfP{}, &gfP{} 177 gfpAdd(d, t2, t2) 178 gfpAdd(t, A, A) 179 gfpAdd(e, t, A) 180 gfpMul(f, e, e) 181 182 gfpAdd(t, d, d) 183 gfpSub(&c.x, f, t) 184 185 gfpAdd(t, C, C) 186 gfpAdd(t2, t, t) 187 gfpAdd(t, t2, t2) 188 gfpSub(&c.y, d, &c.x) 189 gfpMul(t2, e, &c.y) 190 gfpSub(&c.y, t2, t) 191 192 gfpMul(t, &a.y, &a.z) 193 gfpAdd(&c.z, t, t) 194 } 195 196 func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) { 197 precomp := [1 << 2]*curvePoint{nil, {}, {}, {}} 198 precomp[1].Set(a) 199 precomp[2].Set(a) 200 gfpMul(&precomp[2].x, &precomp[2].x, xiTo2PSquaredMinus2Over3) 201 precomp[3].Add(precomp[1], precomp[2]) 202 203 multiScalar := curveLattice.Multi(scalar) 204 205 sum := &curvePoint{} 206 sum.SetInfinity() 207 t := &curvePoint{} 208 209 for i := len(multiScalar) - 1; i >= 0; i-- { 210 t.Double(sum) 211 if multiScalar[i] == 0 { 212 sum.Set(t) 213 } else { 214 sum.Add(t, precomp[multiScalar[i]]) 215 } 216 } 217 c.Set(sum) 218 } 219 220 func (c *curvePoint) MakeAffine() { 221 if c.z == *newGFp(1) { 222 return 223 } else if c.z == *newGFp(0) { 224 c.x = gfP{0} 225 c.y = *newGFp(1) 226 c.t = gfP{0} 227 return 228 } 229 230 zInv := &gfP{} 231 zInv.Invert(&c.z) 232 233 t, zInv2 := &gfP{}, &gfP{} 234 gfpMul(t, &c.y, zInv) 235 gfpMul(zInv2, zInv, zInv) 236 237 gfpMul(&c.x, &c.x, zInv2) 238 gfpMul(&c.y, t, zInv2) 239 240 c.z = *newGFp(1) 241 c.t = *newGFp(1) 242 } 243 244 func (c *curvePoint) Neg(a *curvePoint) { 245 c.x.Set(&a.x) 246 gfpNeg(&c.y, &a.y) 247 c.z.Set(&a.z) 248 c.t = gfP{0} 249 } 250