github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/crypto/secp256k1/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 19:16:36</date> 10 //</624450085127720960> 11 12 //版权所有2010 Go作者。版权所有。 13 //版权所有2011 Thepiachu。版权所有。 14 //版权所有2015 Jeffrey Wilcke、Felix Lange、Gustav Simonsson。版权所有。 15 // 16 //以源和二进制形式重新分配和使用,有或无 17 //允许修改,前提是以下条件 18 //遇见: 19 // 20 //*源代码的再分配必须保留上述版权。 21 //注意,此条件列表和以下免责声明。 22 //*二进制形式的再分配必须复制上述内容 23 //版权声明、此条件列表和以下免责声明 24 //在提供的文件和/或其他材料中, 25 //分布。 26 //*无论是谷歌公司的名称还是其 27 //贡献者可用于支持或推广源自 28 //本软件未经事先明确书面许可。 29 //*不得使用招标人的名称来支持或推广产品。 30 //未经事先书面许可,从本软件派生。 31 // 32 //本软件由版权所有者和贡献者提供。 33 //“原样”和任何明示或暗示的保证,包括但不包括 34 //仅限于对适销性和适用性的暗示保证 35 //不承认特定目的。在任何情况下,版权 36 //所有人或出资人对任何直接、间接、附带的, 37 //特殊、惩戒性或后果性损害(包括但不包括 38 //仅限于采购替代货物或服务;使用损失, 39 //数据或利润;或业务中断),无论如何引起的 40 //责任理论,无论是合同责任、严格责任还是侵权责任。 41 //(包括疏忽或其他)因使用不当而引起的 42 //即使已告知此类损坏的可能性。 43 44 package secp256k1 45 46 import ( 47 "crypto/elliptic" 48 "math/big" 49 "unsafe" 50 ) 51 52 /* 53 #include "libsecp256k1/include/secp256k1.h" 54 extern int secp256k1_ext_scalar_mul(const secp256k1_context*ctx,const unsigned char*point,const unsigned char*scalar); 55 **/ 56 57 import "C" 58 59 const ( 60 //一个大字的位数。 61 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 62 //一个大的.word中的字节数 63 wordBytes = wordBits / 8 64 ) 65 66 //readbits将bigint的绝对值编码为big-endian字节。呼叫者 67 //必须确保buf有足够的空间。如果buf太短,结果将 68 //不完整。 69 func readBits(bigint *big.Int, buf []byte) { 70 i := len(buf) 71 for _, d := range bigint.Bits() { 72 for j := 0; j < wordBytes && i > 0; j++ { 73 i-- 74 buf[i] = byte(d) 75 d >>= 8 76 } 77 } 78 } 79 80 //此代码来自https://github.com/thepiachu/gobit和implements 81 //several Koblitz elliptic curves over prime fields. 82 // 83 //在雅可比坐标系内的曲线法。对于给定的 84 //(x,y)曲线上的位置,雅可比坐标为(x1,y1, 85 //z1) where x = x1/z1² and y = y1/z1³. The greatest speedups come 86 //当整个计算可以在转换中执行时 87 //(如scalarmult和scalarbasemult)。但即使是加和双, 88 //应用和反转转换比在 89 //仿射坐标。 90 91 //Bitcurve表示a=0的Koblitz曲线。 92 //See http://www.hyperelliptic.org/EFD/g1p/auto-shortw.html 93 type BitCurve struct { 94 P *big.Int //基础字段的顺序 95 N *big.Int //基点顺序 96 B *big.Int //比特库夫方程的常数 97 Gx, Gy *big.Int //基点的(x,y) 98 BitSize int //基础字段的大小 99 } 100 101 func (BitCurve *BitCurve) Params() *elliptic.CurveParams { 102 return &elliptic.CurveParams{ 103 P: BitCurve.P, 104 N: BitCurve.N, 105 B: BitCurve.B, 106 Gx: BitCurve.Gx, 107 Gy: BitCurve.Gy, 108 BitSize: BitCurve.BitSize, 109 } 110 } 111 112 //如果给定的(x,y)位于比特币上,isoncurve返回true。 113 func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { 114 //y= x+b 115 y2 := new(big.Int).Mul(y, y) //钇 116 y2.Mod(y2, BitCurve.P) //Y-%P 117 118 x3 := new(big.Int).Mul(x, x) //X 119 x3.Mul(x3, x) //X 120 121 x3.Add(x3, BitCurve.B) //X+B 122 x3.Mod(x3, BitCurve.P) //(x+b)%p 123 124 return x3.Cmp(y2) == 0 125 } 126 127 //TODO:再次检查功能是否正常 128 //雅可比变换的反义形式。查看评论 129 //文件顶部。 130 func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 131 zinv := new(big.Int).ModInverse(z, BitCurve.P) 132 zinvsq := new(big.Int).Mul(zinv, zinv) 133 134 xOut = new(big.Int).Mul(x, zinvsq) 135 xOut.Mod(xOut, BitCurve.P) 136 zinvsq.Mul(zinvsq, zinv) 137 yOut = new(big.Int).Mul(y, zinvsq) 138 yOut.Mod(yOut, BitCurve.P) 139 return 140 } 141 142 //add返回(x1,y1)和(x2,y2)的和 143 func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 144 z := new(big.Int).SetInt64(1) 145 return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) 146 } 147 148 //addjacobian在jacobian坐标中取两点(x1,y1,z1)和 149 //(x2,y2,z2)并返回它们的和,也是雅可比形式。 150 func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 151 //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html addition-add-2007-bl 152 z1z1 := new(big.Int).Mul(z1, z1) 153 z1z1.Mod(z1z1, BitCurve.P) 154 z2z2 := new(big.Int).Mul(z2, z2) 155 z2z2.Mod(z2z2, BitCurve.P) 156 157 u1 := new(big.Int).Mul(x1, z2z2) 158 u1.Mod(u1, BitCurve.P) 159 u2 := new(big.Int).Mul(x2, z1z1) 160 u2.Mod(u2, BitCurve.P) 161 h := new(big.Int).Sub(u2, u1) 162 if h.Sign() == -1 { 163 h.Add(h, BitCurve.P) 164 } 165 i := new(big.Int).Lsh(h, 1) 166 i.Mul(i, i) 167 j := new(big.Int).Mul(h, i) 168 169 s1 := new(big.Int).Mul(y1, z2) 170 s1.Mul(s1, z2z2) 171 s1.Mod(s1, BitCurve.P) 172 s2 := new(big.Int).Mul(y2, z1) 173 s2.Mul(s2, z1z1) 174 s2.Mod(s2, BitCurve.P) 175 r := new(big.Int).Sub(s2, s1) 176 if r.Sign() == -1 { 177 r.Add(r, BitCurve.P) 178 } 179 r.Lsh(r, 1) 180 v := new(big.Int).Mul(u1, i) 181 182 x3 := new(big.Int).Set(r) 183 x3.Mul(x3, x3) 184 x3.Sub(x3, j) 185 x3.Sub(x3, v) 186 x3.Sub(x3, v) 187 x3.Mod(x3, BitCurve.P) 188 189 y3 := new(big.Int).Set(r) 190 v.Sub(v, x3) 191 y3.Mul(y3, v) 192 s1.Mul(s1, j) 193 s1.Lsh(s1, 1) 194 y3.Sub(y3, s1) 195 y3.Mod(y3, BitCurve.P) 196 197 z3 := new(big.Int).Add(z1, z2) 198 z3.Mul(z3, z3) 199 z3.Sub(z3, z1z1) 200 if z3.Sign() == -1 { 201 z3.Add(z3, BitCurve.P) 202 } 203 z3.Sub(z3, z2z2) 204 if z3.Sign() == -1 { 205 z3.Add(z3, BitCurve.P) 206 } 207 z3.Mul(z3, h) 208 z3.Mod(z3, BitCurve.P) 209 210 return x3, y3, z3 211 } 212 213 //双回路2*(x,y) 214 func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 215 z1 := new(big.Int).SetInt64(1) 216 return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) 217 } 218 219 //Doublejacobian在雅可比坐标(x,y,z)中取一点,并且 220 //returns its double, also in Jacobian form. 221 func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 222 //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html doubling-dbl-2009-l 223 224 a := new(big.Int).Mul(x, x) //X1 225 b := new(big.Int).Mul(y, y) //Y1 226 c := new(big.Int).Mul(b, b) //乙 227 228 d := new(big.Int).Add(x, b) //X1+B 229 d.Mul(d, d) //(x1+b) 230 d.Sub(d, a) //(x1+b)-a 231 d.Sub(d, c) //(X1+B)-A—C 232 d.Mul(d, big.NewInt(2)) //2*((x1+b)²-a-c) 233 234 e := new(big.Int).Mul(big.NewInt(3), a) //3*a 235 f := new(big.Int).Mul(e, e) //娥 236 237 x3 := new(big.Int).Mul(big.NewInt(2), d) //2×D 238 x3.Sub(f, x3) //F 2*D 239 x3.Mod(x3, BitCurve.P) 240 241 y3 := new(big.Int).Sub(d, x3) //DX3 242 y3.Mul(e, y3) //E*(D x3) 243 y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D x3)- 8×C 244 y3.Mod(y3, BitCurve.P) 245 246 z3 := new(big.Int).Mul(y, z) //Y1*Z1 247 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 248 z3.Mod(z3, BitCurve.P) 249 250 return x3, y3, z3 251 } 252 253 func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { 254 //确保标量正好是32个字节。我们总是垫,即使 255 //标量的长度为32字节,以避免出现定时侧通道。 256 if len(scalar) > 32 { 257 panic("can't handle scalars > 256 bits") 258 } 259 //注意:潜在的时间问题 260 padded := make([]byte, 32) 261 copy(padded[32-len(scalar):], scalar) 262 scalar = padded 263 264 //用C做乘法,更新点。 265 point := make([]byte, 64) 266 readBits(Bx, point[:32]) 267 readBits(By, point[32:]) 268 269 pointPtr := (*C.uchar)(unsafe.Pointer(&point[0])) 270 scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0])) 271 res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr) 272 273 //解包结果并清除临时文件。 274 x := new(big.Int).SetBytes(point[:32]) 275 y := new(big.Int).SetBytes(point[32:]) 276 for i := range point { 277 point[i] = 0 278 } 279 for i := range padded { 280 scalar[i] = 0 281 } 282 if res != 1 { 283 return nil, nil 284 } 285 return x, y 286 } 287 288 //scalarbasemult返回k*g,其中g是组的基点,k是 289 //大尾数形式的整数。 290 func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 291 return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) 292 } 293 294 //marshal将点转换为ANSI第4.3.6节中指定的格式 295 //X962. 296 func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { 297 byteLen := (BitCurve.BitSize + 7) >> 3 298 ret := make([]byte, 1+2*byteLen) 299 ret[0] = 4 //未压缩点标志 300 readBits(x, ret[1:1+byteLen]) 301 readBits(y, ret[1+byteLen:]) 302 return ret 303 } 304 305 //unmarshal将一个点(由marshal序列化)转换为x,y对。论 306 //误差,x= nIL。 307 func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { 308 byteLen := (BitCurve.BitSize + 7) >> 3 309 if len(data) != 1+2*byteLen { 310 return 311 } 312 if data[0] != 4 { //未压缩形式 313 return 314 } 315 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 316 y = new(big.Int).SetBytes(data[1+byteLen:]) 317 return 318 } 319 320 var theCurve = new(BitCurve) 321 322 func init() { 323 //见第2节第2.7.1节 324 //曲线参数取自: 325 //http://www.secg.org/sec2-v2.pdf 326 theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0) 327 theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0) 328 theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0) 329 theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0) 330 theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0) 331 theCurve.BitSize = 256 332 } 333 334 //s256返回一个实现secp256k1的bitcurve。 335 func S256() *BitCurve { 336 return theCurve 337 } 338