github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/crypto/secp256k1/curve.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2010 Go作者。版权所有。 10 //版权所有2011 Thepiachu。版权所有。 11 //版权所有2015 Jeffrey Wilcke、Felix Lange、Gustav Simonsson。版权所有。 12 // 13 //以源和二进制形式重新分配和使用,有或无 14 //允许修改,前提是以下条件 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 package secp256k1 42 43 import ( 44 "crypto/elliptic" 45 "math/big" 46 "unsafe" 47 ) 48 49 /* 50 包括“libsecp256k1/include/secp256k1.h” 51 extern int secp256k1_ext_scalar_mul(const secp256k1_context*ctx,const unsigned char*point,const unsigned char*scalar); 52 **/ 53 54 import "C" 55 56 const ( 57 //一个大字的位数。 58 wordBits = 32 << (uint64(^big.Word(0)) >> 63) 59 //一个大的.word中的字节数 60 wordBytes = wordBits / 8 61 ) 62 63 //readbits将bigint的绝对值编码为big-endian字节。呼叫者 64 //必须确保buf有足够的空间。如果buf太短,结果将 65 //不完整。 66 func readBits(bigint *big.Int, buf []byte) { 67 i := len(buf) 68 for _, d := range bigint.Bits() { 69 for j := 0; j < wordBytes && i > 0; j++ { 70 i-- 71 buf[i] = byte(d) 72 d >>= 8 73 } 74 } 75 } 76 77 //此代码来自https://github.com/thepiachu/gobit和implements 78 //在素场上的几个Koblitz椭圆曲线。 79 // 80 //在雅可比坐标系内的曲线法。对于给定的 81 //(x,y)曲线上的位置,雅可比坐标为(x1,y1, 82 //z1),其中x=x1/z1?和y=y1/z1?3。最快的加速是 83 //当整个计算可以在转换中执行时 84 //(如scalarmult和scalarbasemult)。但即使是加和双, 85 //应用和反转转换比在 86 //仿射坐标。 87 88 //Bitcurve表示a=0的Koblitz曲线。 89 //请参阅http://www.hypereplication.org/efd/g1p/auto-shortw.html 90 type BitCurve struct { 91 P *big.Int //基础字段的顺序 92 N *big.Int //基点顺序 93 B *big.Int //比特库夫方程的常数 94 Gx, Gy *big.Int //基点的(x,y) 95 BitSize int //基础字段的大小 96 } 97 98 func (BitCurve *BitCurve) Params() *elliptic.CurveParams { 99 return &elliptic.CurveParams{ 100 P: BitCurve.P, 101 N: BitCurve.N, 102 B: BitCurve.B, 103 Gx: BitCurve.Gx, 104 Gy: BitCurve.Gy, 105 BitSize: BitCurve.BitSize, 106 } 107 } 108 109 //如果给定的(x,y)位于比特币上,isoncurve返回true。 110 func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool { 111 //y= x+b 112 y2 := new(big.Int).Mul(y, y) //钇 113 y2.Mod(y2, BitCurve.P) //Y-%P 114 115 x3 := new(big.Int).Mul(x, x) //X 116 x3.Mul(x3, x) //X 117 118 x3.Add(x3, BitCurve.B) //X+B 119 x3.Mod(x3, BitCurve.P) //(x+b)%p 120 121 return x3.Cmp(y2) == 0 122 } 123 124 //TODO:再次检查功能是否正常 125 //雅可比变换的反义形式。查看评论 126 //文件顶部。 127 func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) { 128 zinv := new(big.Int).ModInverse(z, BitCurve.P) 129 zinvsq := new(big.Int).Mul(zinv, zinv) 130 131 xOut = new(big.Int).Mul(x, zinvsq) 132 xOut.Mod(xOut, BitCurve.P) 133 zinvsq.Mul(zinvsq, zinv) 134 yOut = new(big.Int).Mul(y, zinvsq) 135 yOut.Mod(yOut, BitCurve.P) 136 return 137 } 138 139 //add返回(x1,y1)和(x2,y2)的和 140 func (BitCurve *BitCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) { 141 z := new(big.Int).SetInt64(1) 142 return BitCurve.affineFromJacobian(BitCurve.addJacobian(x1, y1, z, x2, y2, z)) 143 } 144 145 //addjacobian在jacobian坐标中取两点(x1,y1,z1)和 146 //(x2,y2,z2)并返回它们的和,也是雅可比形式。 147 func (BitCurve *BitCurve) addJacobian(x1, y1, z1, x2, y2, z2 *big.Int) (*big.Int, *big.Int, *big.Int) { 148 //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html addition-add-2007-bl 149 z1z1 := new(big.Int).Mul(z1, z1) 150 z1z1.Mod(z1z1, BitCurve.P) 151 z2z2 := new(big.Int).Mul(z2, z2) 152 z2z2.Mod(z2z2, BitCurve.P) 153 154 u1 := new(big.Int).Mul(x1, z2z2) 155 u1.Mod(u1, BitCurve.P) 156 u2 := new(big.Int).Mul(x2, z1z1) 157 u2.Mod(u2, BitCurve.P) 158 h := new(big.Int).Sub(u2, u1) 159 if h.Sign() == -1 { 160 h.Add(h, BitCurve.P) 161 } 162 i := new(big.Int).Lsh(h, 1) 163 i.Mul(i, i) 164 j := new(big.Int).Mul(h, i) 165 166 s1 := new(big.Int).Mul(y1, z2) 167 s1.Mul(s1, z2z2) 168 s1.Mod(s1, BitCurve.P) 169 s2 := new(big.Int).Mul(y2, z1) 170 s2.Mul(s2, z1z1) 171 s2.Mod(s2, BitCurve.P) 172 r := new(big.Int).Sub(s2, s1) 173 if r.Sign() == -1 { 174 r.Add(r, BitCurve.P) 175 } 176 r.Lsh(r, 1) 177 v := new(big.Int).Mul(u1, i) 178 179 x3 := new(big.Int).Set(r) 180 x3.Mul(x3, x3) 181 x3.Sub(x3, j) 182 x3.Sub(x3, v) 183 x3.Sub(x3, v) 184 x3.Mod(x3, BitCurve.P) 185 186 y3 := new(big.Int).Set(r) 187 v.Sub(v, x3) 188 y3.Mul(y3, v) 189 s1.Mul(s1, j) 190 s1.Lsh(s1, 1) 191 y3.Sub(y3, s1) 192 y3.Mod(y3, BitCurve.P) 193 194 z3 := new(big.Int).Add(z1, z2) 195 z3.Mul(z3, z3) 196 z3.Sub(z3, z1z1) 197 if z3.Sign() == -1 { 198 z3.Add(z3, BitCurve.P) 199 } 200 z3.Sub(z3, z2z2) 201 if z3.Sign() == -1 { 202 z3.Add(z3, BitCurve.P) 203 } 204 z3.Mul(z3, h) 205 z3.Mod(z3, BitCurve.P) 206 207 return x3, y3, z3 208 } 209 210 //双回路2*(x,y) 211 func (BitCurve *BitCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) { 212 z1 := new(big.Int).SetInt64(1) 213 return BitCurve.affineFromJacobian(BitCurve.doubleJacobian(x1, y1, z1)) 214 } 215 216 //Doublejacobian在雅可比坐标(x,y,z)中取一点,并且 217 //返回它的双,也以Jacobian的形式。 218 func (BitCurve *BitCurve) doubleJacobian(x, y, z *big.Int) (*big.Int, *big.Int, *big.Int) { 219 //请参见http://hyper椭圆形.org/efd/g1p/auto-shortw-jacobian-0.html doubling-dbl-2009-l 220 221 a := new(big.Int).Mul(x, x) //X1 222 b := new(big.Int).Mul(y, y) //Y1 223 c := new(big.Int).Mul(b, b) //乙 224 225 d := new(big.Int).Add(x, b) //X1+B 226 d.Mul(d, d) //(x1+b) 227 d.Sub(d, a) //(x1+b)-a 228 d.Sub(d, c) //(X1+B)-A—C 229 d.Mul(d, big.NewInt(2)) //2*((x1+b)²-a-c) 230 231 e := new(big.Int).Mul(big.NewInt(3), a) //3*a 232 f := new(big.Int).Mul(e, e) //娥 233 234 x3 := new(big.Int).Mul(big.NewInt(2), d) //2×D 235 x3.Sub(f, x3) //F 2*D 236 x3.Mod(x3, BitCurve.P) 237 238 y3 := new(big.Int).Sub(d, x3) //DX3 239 y3.Mul(e, y3) //E*(D x3) 240 y3.Sub(y3, new(big.Int).Mul(big.NewInt(8), c)) //E*(D x3)- 8×C 241 y3.Mod(y3, BitCurve.P) 242 243 z3 := new(big.Int).Mul(y, z) //Y1*Z1 244 z3.Mul(big.NewInt(2), z3) //3*Y1*Z1 245 z3.Mod(z3, BitCurve.P) 246 247 return x3, y3, z3 248 } 249 250 func (BitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, *big.Int) { 251 //确保标量正好是32个字节。我们总是垫,即使 252 //标量的长度为32字节,以避免出现定时侧通道。 253 if len(scalar) > 32 { 254 panic("can't handle scalars > 256 bits") 255 } 256 //注意:潜在的时间问题 257 padded := make([]byte, 32) 258 copy(padded[32-len(scalar):], scalar) 259 scalar = padded 260 261 //用C做乘法,更新点。 262 point := make([]byte, 64) 263 readBits(Bx, point[:32]) 264 readBits(By, point[32:]) 265 266 pointPtr := (*C.uchar)(unsafe.Pointer(&point[0])) 267 scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0])) 268 res := C.secp256k1_ext_scalar_mul(context, pointPtr, scalarPtr) 269 270 //解包结果并清除临时文件。 271 x := new(big.Int).SetBytes(point[:32]) 272 y := new(big.Int).SetBytes(point[32:]) 273 for i := range point { 274 point[i] = 0 275 } 276 for i := range padded { 277 scalar[i] = 0 278 } 279 if res != 1 { 280 return nil, nil 281 } 282 return x, y 283 } 284 285 //scalarbasemult返回k*g,其中g是组的基点,k是 286 //大尾数形式的整数。 287 func (BitCurve *BitCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 288 return BitCurve.ScalarMult(BitCurve.Gx, BitCurve.Gy, k) 289 } 290 291 //marshal将点转换为ANSI第4.3.6节中指定的格式 292 //X962. 293 func (BitCurve *BitCurve) Marshal(x, y *big.Int) []byte { 294 byteLen := (BitCurve.BitSize + 7) >> 3 295 ret := make([]byte, 1+2*byteLen) 296 ret[0] = 4 //未压缩点标志 297 readBits(x, ret[1:1+byteLen]) 298 readBits(y, ret[1+byteLen:]) 299 return ret 300 } 301 302 //unmarshal将一个点(由marshal序列化)转换为x,y对。论 303 //误差,x= nIL。 304 func (BitCurve *BitCurve) Unmarshal(data []byte) (x, y *big.Int) { 305 byteLen := (BitCurve.BitSize + 7) >> 3 306 if len(data) != 1+2*byteLen { 307 return 308 } 309 if data[0] != 4 { //未压缩形式 310 return 311 } 312 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 313 y = new(big.Int).SetBytes(data[1+byteLen:]) 314 return 315 } 316 317 var theCurve = new(BitCurve) 318 319 func init() { 320 //见第2节第2.7.1节 321 //曲线参数取自: 322 //http://www.secg.org/collateral/sec2_final.pdf 323 theCurve.P, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 0) 324 theCurve.N, _ = new(big.Int).SetString("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 0) 325 theCurve.B, _ = new(big.Int).SetString("0x0000000000000000000000000000000000000000000000000000000000000007", 0) 326 theCurve.Gx, _ = new(big.Int).SetString("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 0) 327 theCurve.Gy, _ = new(big.Int).SetString("0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 0) 328 theCurve.BitSize = 256 329 } 330 331 //s256返回一个实现secp256k1的bitcurve。 332 func S256() *BitCurve { 333 return theCurve 334 }