github.com/emmansun/gmsm@v0.29.1/internal/sm2ec/sm2p256_mqv.go (about) 1 package sm2ec 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "math/bits" 7 ) 8 9 var p256Order = [4]uint64{0x53bbf40939d54123, 0x7203df6b21c6052b, 10 0xffffffffffffffff, 0xfffffffeffffffff} 11 12 func fromBytes(bytes []byte) (*[4]uint64, error) { 13 if len(bytes) != 32 { 14 return nil, errors.New("invalid scalar length") 15 } 16 var t [4]uint64 17 t[0] = binary.BigEndian.Uint64(bytes[24:]) 18 t[1] = binary.BigEndian.Uint64(bytes[16:]) 19 t[2] = binary.BigEndian.Uint64(bytes[8:]) 20 t[3] = binary.BigEndian.Uint64(bytes) 21 return &t, nil 22 } 23 24 func toBytes(t *[4]uint64) []byte { 25 var bytes [32]byte 26 27 binary.BigEndian.PutUint64(bytes[:], t[3]) 28 binary.BigEndian.PutUint64(bytes[8:], t[2]) 29 binary.BigEndian.PutUint64(bytes[16:], t[1]) 30 binary.BigEndian.PutUint64(bytes[24:], t[0]) 31 32 return bytes[:] 33 } 34 35 // p256OrdAdd sets res = x + y. 36 func p256OrdAdd(res, x, y *[4]uint64) { 37 var c, b uint64 38 t1 := make([]uint64, 4) 39 t1[0], c = bits.Add64(x[0], y[0], 0) 40 t1[1], c = bits.Add64(x[1], y[1], c) 41 t1[2], c = bits.Add64(x[2], y[2], c) 42 t1[3], c = bits.Add64(x[3], y[3], c) 43 t2 := make([]uint64, 4) 44 t2[0], b = bits.Sub64(t1[0], p256Order[0], 0) 45 t2[1], b = bits.Sub64(t1[1], p256Order[1], b) 46 t2[2], b = bits.Sub64(t1[2], p256Order[2], b) 47 t2[3], b = bits.Sub64(t1[3], p256Order[3], b) 48 // Three options: 49 // - a+b < p 50 // then c is 0, b is 1, and t1 is correct 51 // - p <= a+b < 2^256 52 // then c is 0, b is 0, and t2 is correct 53 // - 2^256 <= a+b 54 // then c is 1, b is 1, and t2 is correct 55 t2Mask := (c ^ b) - 1 56 res[0] = (t1[0] & ^t2Mask) | (t2[0] & t2Mask) 57 res[1] = (t1[1] & ^t2Mask) | (t2[1] & t2Mask) 58 res[2] = (t1[2] & ^t2Mask) | (t2[2] & t2Mask) 59 res[3] = (t1[3] & ^t2Mask) | (t2[3] & t2Mask) 60 } 61 62 func ImplicitSig(sPriv, ePriv, t []byte) ([]byte, error) { 63 mulRes, err := P256OrdMul(ePriv, t) 64 if err != nil { 65 return nil, err 66 } 67 t1, err := fromBytes(mulRes) 68 if err != nil { 69 return nil, err 70 } 71 t2, err := fromBytes(sPriv) 72 if err != nil { 73 return nil, err 74 } 75 var t3 [4]uint64 76 p256OrdAdd(&t3, t1, t2) 77 return toBytes(&t3), nil 78 }