github.com/hellobchain/newcryptosm@v0.0.0-20221019060107-edb949a317e9/sm9/curve_interface.go (about) 1 package sm9 2 3 import ( 4 "math/big" 5 ) 6 7 // type impl struct{} 8 9 /* 10 type ECCInternal interface { 11 AffineToPoint(x, y *big.Int) (point *ECCInternalPoint) 12 PointToAffine(point *ECCInternalPoint) (x, y *big.Int) 13 //JacobianAdd(p1, p2 *ECCInternalPoint) (r *ECCInternalPoint, equal int) 14 JacobianAdd(p1, p2 *ECCInternalPoint) (r *ECCInternalPoint) 15 JacobianDouble(p1 *ECCInternalPoint) (r *ECCInternalPoint) 16 PointNegCondition(p1 *ECCInternalPoint, c int) 17 FieldMul(res, in1, in2 []uint64) 18 MontgomaryR() []uint64 19 MontgomaryR2() []uint64 20 ModSqrtP(a *big.Int) *big.Int 21 ModInverseP(a []uint64) []uint64 22 ModInverseOrder(a *big.Int) *big.Int 23 } 24 25 type ECCInternalPoint struct { 26 XYZ [12]uint64 27 } 28 */ 29 // func New() supercurve.JacobianIF { //name is not good 30 // return &impl{} 31 // } 32 33 func InternalP2CurveP(xyz *[12]uint64) (out *curvePoint) { 34 out = &curvePoint{} 35 copy(out.x[:], xyz[0:4]) 36 copy(out.y[:], xyz[4:8]) 37 copy(out.z[:], xyz[8:12]) 38 return 39 } 40 41 func InternalP2CurveAffineP(xyz *[12]uint64) (out *curvePointAffine) { 42 out = &curvePointAffine{} 43 copy(out.x[:], xyz[0:4]) 44 copy(out.y[:], xyz[4:8]) 45 return 46 } 47 48 func CurveP2InternalP(point *curvePoint) (out *[12]uint64) { 49 out = &[12]uint64{} 50 copy(out[0:4], point.x[:]) 51 copy(out[4:8], point.y[:]) 52 copy(out[8:12], point.z[:]) 53 return 54 } 55 56 func AffineToPoint(x, y *big.Int) (xyz *[12]uint64) { 57 58 xyz = &[12]uint64{} 59 60 t := new(big.Int).Mul(x, mogo_bigInt) 61 t.Mod(t, p) 62 fromBig(xyz[0:4], t) // change x to montgomery format 63 64 t.Mul(y, mogo_bigInt) 65 t.Mod(t, p) 66 fromBig(xyz[4:8], t) // change y to montgomery format 67 68 xyz[8] = 0x1a9064d81caeba83 69 xyz[9] = 0xde0d6cb4e5851124 70 xyz[10] = 0x29fc54b00a7138ba 71 xyz[11] = 0x49bffffffd5c590e 72 73 return 74 } 75 76 func PointToAffine(xyz *[12]uint64) (x, y *big.Int) { 77 78 ret1 := make([]byte, 32) 79 ret2 := make([]byte, 32) 80 81 temp := InternalP2CurveP(xyz) 82 temp.MakeAffine() 83 84 montDecode(&temp.x, &temp.x) 85 montDecode(&temp.y, &temp.y) 86 87 temp.x.Marshal(ret1) 88 temp.y.Marshal(ret2) 89 90 x1 := new(big.Int).SetBytes(ret1) 91 y1 := new(big.Int).SetBytes(ret2) 92 93 return x1, y1 94 } 95 96 func JacobianAdd(p1, p2 *[12]uint64) (r1 *[12]uint64) { 97 98 t1 := InternalP2CurveP(p1) 99 t2 := InternalP2CurveP(p2) 100 t1.Add(t1, t2) 101 102 r1 = CurveP2InternalP(t1) 103 return 104 } 105 106 func JacobianAddAffine(p1, p2 *[12]uint64) (r1 *[12]uint64) { 107 108 t1 := InternalP2CurveP(p1) 109 t2 := InternalP2CurveAffineP(p2) 110 t1.Add_JA(t1, t2) 111 112 r1 = CurveP2InternalP(t1) 113 return 114 } 115 116 func JacobianDouble(p1 *[12]uint64) (r1 *[12]uint64) { 117 t1 := InternalP2CurveP(p1) 118 t1.Double(t1) 119 r1 = CurveP2InternalP(t1) 120 return 121 } 122 123 func PointNegCondition(p1 *[12]uint64, condition int) { //if c!=0, p1 <--(-p1) 124 if condition == 0 { 125 return 126 } 127 t1 := InternalP2CurveP(p1) 128 t1.Neg(t1) 129 copy(p1[0:4], t1.x[:]) 130 copy(p1[4:8], t1.y[:]) 131 copy(p1[8:12], t1.z[:]) 132 return 133 } 134 135 func isOdd(a *big.Int) bool { 136 return a.Bit(0) == 1 137 } 138 139 // decompressPoint decompresses a point on the given curve given the X point and the solution to use. 140 func DecompressPointX4Y(x *big.Int, ybit bool) *big.Int { 141 // x³ - 3x + b 142 x3 := new(big.Int).Mul(x, x) 143 x3.Mul(x3, x) 144 145 // threeX := new(big.Int).Lsh(x, 1) 146 // threeX.Add(threeX, x) 147 148 // x3.Sub(x3, threeX) 149 x3.Add(x3, big.NewInt(5)) 150 x3.Mod(x3, Sm9_p) 151 152 //y := new(big.Int).ModSqrt(x3, curve.Params().P) 153 //y := new(big.Int) 154 //y:=new(big.Int).ModSqrt(x3, SM9().Params().P) 155 y := ModSqrtP(x3) 156 157 if y == nil { 158 return nil 159 } 160 161 if ybit != isOdd(y) { 162 y.Sub(Sm9_p, y) 163 } 164 165 return y 166 } 167 168 // Compress compress a point to a byte string 169 func CompressP(x, y *big.Int) []byte { 170 if x.Sign() == 0 && y.Sign() == 0 { 171 return []byte{0x00} 172 } 173 //byteLen := (sm9inter.SM9().Params().BitSize+7)/8 174 byteLen := 32 175 176 ret := make([]byte, 1+byteLen) 177 if y.Bit(0) == 0 { 178 ret[0] = 0x02 179 } else { 180 ret[0] = 0x03 181 } 182 183 xBytes := x.Bytes() 184 copy(ret[byteLen-len(xBytes)+1:], xBytes) 185 return ret 186 } 187 188 // Decompress decompress a byte string to a point 189 func DecompressP(data []byte) (x, y *big.Int) { 190 if data == nil { 191 return nil, nil 192 } 193 if len(data) == 0 { 194 return nil, nil 195 } 196 //byteLen := (sm9inter.SM9().Params().BitSize+7)/8 197 byteLen := 32 198 switch data[0] { 199 case 0x00: 200 if len(data) == 1 { 201 return new(big.Int), new(big.Int) 202 } 203 return nil, nil 204 case 0x02, 0x03: 205 { 206 if len(data) != 1+byteLen { 207 return nil, nil 208 } 209 x = new(big.Int).SetBytes(data[1:]) 210 211 // x³ + b 212 x3 := new(big.Int).Mul(x, x) 213 x3.Mul(x3, x) 214 215 x3.Add(x3, big.NewInt(5)) 216 x3.Mod(x3, Sm9_p) 217 218 y := ModSqrtP(x3) 219 220 if y == nil { 221 return nil, nil 222 } 223 if y.Bit(0) != uint(data[0]&0x01) { 224 y.Sub(Sm9_p, y) 225 } 226 return x, y 227 } 228 case 0x04: 229 { 230 x = new(big.Int).SetBytes(data[1 : 1+byteLen]) 231 y = new(big.Int).SetBytes(data[1+byteLen:]) 232 return x, y 233 } 234 default: 235 return nil, nil 236 } 237 } 238 239 func FieldMul(res, in1, in2 []uint64) { //res,in1,in2:mogo format 240 var temp1 = &gfP{in1[0], in1[1], in1[2], in1[3]} 241 var temp2 = &gfP{in2[0], in2[1], in2[2], in2[3]} 242 gfpMul(temp2, temp2, temp1) 243 for i := 0; i < 4; i++ { 244 res[i] = temp2[i] 245 } 246 } 247 248 func MontgomaryR() []uint64 { 249 return []uint64{0x1a9064d81caeba83, 0xde0d6cb4e5851124, 0x29fc54b00a7138ba, 0x49bffffffd5c590e} 250 } 251 252 func MontgomaryR2() []uint64 { 253 return []uint64{0x27dea312b417e2d2, 0x88f8105fae1a5d3f, 0xe479b522d6706e7b, 0x2ea795a656f62fbd} 254 //2ea795a656f62fbd e479b522d6706e7b 88f8105fae1a5d3f 27dea312b417e2d2 255 } 256 257 /* 258 func (c *impl) ModSqrtP(a *big.Int) *big.Int { 259 var temp = big.NewInt(1) 260 temp.ModSqrt(a, p) 261 return temp 262 } 263 */ 264 265 func ModSqrtP(a *big.Int) *big.Int { //a>=0,a!=2;//ALG see:SM_1_P29 266 267 var temp = big.NewInt(1) 268 var one = big.NewInt(1) 269 var fone = big.NewInt(-1) 270 fone.Mod(fone, p) 271 temp.Exp(a, const2uplus1, p) //g^(2u+1) 272 273 if temp.Cmp(one) == 0 { 274 temp.Exp(a, constuplus1, p) 275 } else if temp.Cmp(fone) == 0 { 276 one.Add(a, a) //2g 277 one.Mod(one, p) 278 fone.Add(one, one) //4g 279 fone.Mod(fone, p) 280 fone.Exp(fone, constu, p) 281 fone.Mul(fone, one) 282 fone.Mod(fone, p) 283 temp.Set(fone) 284 } else { 285 return a 286 } 287 return temp 288 } 289 290 //func montEncode(c, a *gfP) { gfpMul(c, a, r2) } 291 func ModInverseP(a []uint64) []uint64 { //a: mogo format;return mogo format too; 292 temp := &gfP{a[0], a[1], a[2], a[3]} 293 temp.Invert(temp) 294 295 X := make([]uint64, 4) 296 for i := 0; i < 4; i++ { 297 X[i] = temp[i] 298 } 299 return X 300 } 301 302 func ModInverseOrder(a *big.Int) *big.Int { 303 var b = big.NewInt(1) 304 b.ModInverse(a, Order) 305 return b 306 } 307 308 func InitBigTable(Bx, By *big.Int) *[43][32 * 8]uint64 { 309 var precomputed [43][32 * 8]uint64 310 311 btpoint := AffineToPoint(Bx, By) 312 313 basepoint := &curvePoint{} 314 for i := 0; i < 4; i++ { 315 basepoint.x[i] = btpoint[i] 316 basepoint.y[i] = btpoint[i+4] 317 basepoint.z[i] = btpoint[i+8] 318 } 319 320 t1 := new(G1).Set(&G1{basepoint}) 321 t2 := new(G1).Set(&G1{basepoint}) 322 t3 := new(G1).Set(&G1{basepoint}) 323 var count int 324 for j := 0; j < 32; j++ { 325 t1.Set(t2) 326 327 for i := 0; i < 43; i++ { 328 // The window size is 6 so we need to double 6 times. 329 if i != 0 { 330 for k := 0; k < 6; k++ { 331 //p256PointDoubleAsm(t1, t1) 332 t3.p.Double(t1.p) 333 t1.Set(t3) 334 } 335 } 336 337 t1.p.MakeAffine() 338 t1.p.z[0] = 0x1a9064d81caeba83 339 t1.p.z[1] = 0xde0d6cb4e5851124 340 t1.p.z[2] = 0x29fc54b00a7138ba 341 t1.p.z[3] = 0x49bffffffd5c590e 342 343 if t1.p.IsInfinity() { 344 for count = 0; count < 4; count++ { 345 precomputed[i][j*8+count] = 0 346 precomputed[i][j*8+count+4] = 0 347 } 348 } 349 for count = 0; count < 4; count++ { 350 precomputed[i][j*8+count] = t1.p.x[count] 351 precomputed[i][j*8+count+4] = t1.p.y[count] 352 } 353 354 } 355 if j == 0 { 356 //p256PointDoubleAsm(t2, basePoint) 357 t2.p.Double(basepoint) 358 } else { //t2:3-->32G 359 t2.p.Add(t2.p, basepoint) 360 } 361 } 362 return &precomputed 363 }