Commit e89c3116 authored by 袁邓@五瓣科技's avatar 袁邓@五瓣科技

根据接口信息做相应修改

parent 938d11dd
...@@ -5,6 +5,7 @@ import ( ...@@ -5,6 +5,7 @@ import (
pb "github.com/hyperledger/fabric/protos/peer" pb "github.com/hyperledger/fabric/protos/peer"
"fmt" "fmt"
"encoding/json" "encoding/json"
"strings"
) )
const KEY = "COUPONS-" const KEY = "COUPONS-"
...@@ -59,18 +60,22 @@ func getCouponsApi(args []string, stub shim.ChaincodeStubInterface) pb.Response ...@@ -59,18 +60,22 @@ func getCouponsApi(args []string, stub shim.ChaincodeStubInterface) pb.Response
return shim.Success(coupByte) return shim.Success(coupByte)
} }
// 入参:utxo地址,证书、交易签名 // 入参:utxo地址,证书、交易签名.商家查看,只能查看已领取的UTXO
func getCouponsByAddressApi(args []string, stub shim.ChaincodeStubInterface) pb.Response { func getCouponsByAddressApi(args []string, stub shim.ChaincodeStubInterface) pb.Response {
// 解析请求数据 // 解析请求数据
trans,_,_,err := messageToTrans(CreateCoupon,args,stub) trans,_,_,err := messageToTrans(UseCoupon,args,stub)
if err != nil{ if err != nil{
return shim.Error(err.Error()) return shim.Error(err.Error())
} }
//查询utxo信息 //查询utxo信息
utxoByte,err :=getStateByte(KEY+trans.From,stub) utxo,err :=getStateUtxo(KEY+trans.From,stub)
if err != nil{ if err != nil{
return shim.Error(err.Error()) return shim.Error(err.Error())
} }
if strings.Compare(utxo.Status,"2") != 0{
return shim.Error("Query for exceptions, UTXO status exceptions")
}
utxoByte,_ :=json.Marshal(utxo)
return shim.Success(utxoByte) return shim.Success(utxoByte)
} }
......
...@@ -309,4 +309,17 @@ func TestCouponsFlow(t *testing.T){ ...@@ -309,4 +309,17 @@ func TestCouponsFlow(t *testing.T){
responseByPutschema = stub.MockInvoke("invoke1",[][]byte{[]byte("createTx/useCoupon"),[]byte("111"),[]byte(useCouponsDate),[]byte(useCouponsSign)}) responseByPutschema = stub.MockInvoke("invoke1",[][]byte{[]byte("createTx/useCoupon"),[]byte("111"),[]byte(useCouponsDate),[]byte(useCouponsSign)})
fmt.Printf("Invoke status %d,message %s and payload %s\n",responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload)) fmt.Printf("Invoke status %d,message %s and payload %s\n",responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
//fmt.Println("========================================query getCoupons============================================")
//fmt.Println()
//fmt.Println()
//responseByPutschema = stub.MockInvoke("invoke1",[][]byte{[]byte("getCoupons"),[]byte("111"),[]byte(useCouponsDate),[]byte(useCouponsSign)})
//fmt.Printf("Invoke status %d,message %s and payload %s\n",responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
//
//fmt.Println("========================================query getCouponsByAddress============================================")
//fmt.Println()
//fmt.Println()
//responseByPutschema = stub.MockInvoke("invoke1",[][]byte{[]byte("getCouponsByAddress"),[]byte("111"),[]byte(useCouponsDate),[]byte(useCouponsSign)})
//fmt.Printf("Invoke status %d,message %s and payload %s\n",responseByPutschema.Status,responseByPutschema.Message,string(responseByPutschema.Payload))
} }
...@@ -7,7 +7,6 @@ import ( ...@@ -7,7 +7,6 @@ import (
"github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/chaincode/shim"
"time" "time"
) )
//券结构 //券结构
type Coupons struct { type Coupons struct {
CoupId string `json:"coup_id"` //券id CoupId string `json:"coup_id"` //券id
...@@ -19,7 +18,6 @@ type Coupons struct { ...@@ -19,7 +18,6 @@ type Coupons struct {
CoupQuantity int `json:"coup_quantity"` //发行数量 CoupQuantity int `json:"coup_quantity"` //发行数量
CoupAmount float64 `json:"coup_amount"` //面额 CoupAmount float64 `json:"coup_amount"` //面额
CoupDiscount float64 `json:"coup_discount"` //折扣 CoupDiscount float64 `json:"coup_discount"` //折扣
CoupTotalAmount float64 `json:"coup_total_amount"` //券总金额
FloorAmount float64 `json:"floor_amount"` //券使用门槛,最低消费金额 FloorAmount float64 `json:"floor_amount"` //券使用门槛,最低消费金额
UseMerchats []string `json:"use_merchats"` //当前券支持的商户Id UseMerchats []string `json:"use_merchats"` //当前券支持的商户Id
UseMerchantsType *MerchantsType `json:"use_merchants_type"` UseMerchantsType *MerchantsType `json:"use_merchants_type"`
...@@ -38,7 +36,6 @@ type CoupAvailable struct { ...@@ -38,7 +36,6 @@ type CoupAvailable struct {
StartTime string `json:"start_time"` StartTime string `json:"start_time"`
EndTime string `json:"end_time"` EndTime string `json:"end_time"`
} }
//UTXO结构 //UTXO结构
type Utxo struct { type Utxo struct {
Address string `json:"address"` //Utxo记录地址 Address string `json:"address"` //Utxo记录地址
...@@ -63,10 +60,10 @@ type Order struct { ...@@ -63,10 +60,10 @@ type Order struct {
//用户信息 //用户信息
type UserInfo struct { type UserInfo struct {
Uid string `json:"uid"` //用户id Uid string `json:"uid"` //用户id
Name string `json:"name"` //用户名 Name string `json:"name"` //用户名
Number string `json:"number"` //身份证号 IdNumber string `json:"id_number"` //身份证号
Phone string `json:"phone"` //手机号 PhoneNumber string `json:"phone_number"` //手机号
CreateTime time.Time `json:"create_time"` //创建时间 CreateTime time.Time `json:"create_time"` //创建时间
} }
......
...@@ -6,7 +6,6 @@ import ( ...@@ -6,7 +6,6 @@ import (
pb "github.com/hyperledger/fabric/protos/peer" pb "github.com/hyperledger/fabric/protos/peer"
"encoding/json" "encoding/json"
"strings" "strings"
"encoding/hex"
) )
func transactionProcess(paths, args []string, stub shim.ChaincodeStubInterface) pb.Response { func transactionProcess(paths, args []string, stub shim.ChaincodeStubInterface) pb.Response {
...@@ -255,15 +254,21 @@ func useCouponApi(args []string, stub shim.ChaincodeStubInterface) pb.Response { ...@@ -255,15 +254,21 @@ func useCouponApi(args []string, stub shim.ChaincodeStubInterface) pb.Response {
if err != nil{ if err != nil{
fmt.Println(err) fmt.Println(err)
} }
privHex, ok := dat["privHex"].(string) //拿到订单信息
order, ok := dat["order"].(string)
//订单签名信息
orderSign, ok := dat["orderSign"].(string)
if !ok { if !ok {
return shim.Error("Error privHex parameter type,must be string") return shim.Error("Error orderSign parameter type,must be string")
} }
_,pubKey,err := ParsePrivateKey(privHex) //TODO 验证订单签名信息
pubHex := hex.EncodeToString(pubKey) fmt.Println(order)
if utxo.PublicKey != pubHex { fmt.Println(orderSign)
return shim.Error("coupons verify error") //_,pubKey,err := ParsePrivateKey(privHex)
} //pubHex := hex.EncodeToString(pubKey)
//if utxo.PublicKey != pubHex {
// return shim.Error("coupons verify error")
//}
utxo.Status = "3" utxo.Status = "3"
var mertNewUtxo Utxo var mertNewUtxo Utxo
mertByteUtxo, _ := stub.GetState(KEY+trans.To) mertByteUtxo, _ := stub.GetState(KEY+trans.To)
......
//package main
package sm_crypto
import (
"crypto/elliptic"
"encoding/hex"
"errors"
"fmt"
"github.com/TMChain/go-TMChain/common"
"github.com/TMChain/go-TMChain/common/math"
"github.com/TMChain/go-TMChain/crypto/crypto_interface"
"github.com/TMChain/go-TMChain/crypto/sm_crypto/sm2"
"github.com/TMChain/go-TMChain/crypto/sm_crypto/sm3"
"github.com/TMChain/go-TMChain/rlp"
"io"
"io/ioutil"
"math/big"
"os"
"C"
"github.com/TMChain/go-TMChain/common/hexutil"
)
func main() {
}
var errInvalidSm2Pubkey = errors.New("invalid sm2 public key")
//export C_Hash256
func C_Hash256(dataC *C.char) *C.char {
data := C.GoString(dataC)
s := sm3.New()
s.Write(common.FromHex(data))
return C.CString(hexutil.Encode(s.Sum(nil)))
}
//export C_Hash256Bysha3
func C_Hash256Bysha3(dataC *C.char) *C.char {
//data := C.GoString(dataC)
////s := sha3.New256()
//s := sha3.NewLegacyKeccak256()
//s.Write(common.FromHex(data))
//
//return C.CString(hexutil.Encode(s.Sum(nil)))
return nil
}
//export C_Sign
func C_Sign(hashC *C.char, prvC *C.char) (*C.char) {
hash := C.GoString(hashC)
prv := C.GoString(prvC)
priv, err := toPriKey_c(common.FromHex(prv))
if err != nil {
return C.CString("")
}
if len(common.FromHex(hash)) != 32 {
return C.CString("")
}
sigRet, err := sm2.SM2Sign(&sm2.PrivateKey{
PublicKey: sm2.PublicKey{Curve: priv.Curve, X: priv.X, Y: priv.Y},
D: priv.D,
}, common.FromHex(hash))
if err != nil {
return C.CString("")
}
return C.CString(hexutil.Encode(sigRet))
}
//export C_GenerateKey
func C_GenerateKey() (*C.char) {
eprk, err := sm2.GenerateKey()
if err != nil {
return C.CString("")
}
priv := &icrypto.PrivateKey{
PublicKey: icrypto.PublicKey{
Curve: eprk.Curve,
X: eprk.X,
Y: eprk.Y,
},
D: eprk.D,
}
return C.CString(fromPriKey_c(priv))
}
//export C_FromPrv
func C_FromPrv(prvC *C.char)(*C.char) {
prv := C.GoString(prvC)
priv, err := toPriKey_c(common.FromHex(prv))
if err != nil {
return C.CString("")
}
smC := new(SmCrypto)
pubByte := smC.FromPub(&priv.PublicKey)
return C.CString(hexutil.Encode(pubByte))
}
//export C_VerifySignature
func C_VerifySignature(pubkeyC, hashC, signatureC *C.char) bool {
hash := C.GoString(hashC)
pubkey := C.GoString(pubkeyC)
signature := C.GoString(signatureC)
pub, err := unmarshalPubkey_c(common.FromHex(pubkey))
if err != nil {
return false
}
if sm2.VerifySign(&sm2.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}, common.FromHex(hash), common.FromHex(signature)) {
return true
}
return false
}
// FromECDSA exports a private key into a binary dump.
func fromSm2_c(priv *icrypto.PrivateKey) []byte {
if priv == nil {
return nil
}
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
}
func fromPriKey_c(priv *icrypto.PrivateKey) string {
return common.ToHex(fromSm2_c(priv))
}
func toPriKey_c(d []byte) (*icrypto.PrivateKey, error) {
return toSm2_c(d)
}
func toSm2_c(d []byte) (*icrypto.PrivateKey, error) {
return toSm2(d, true)
}
func unmarshalPubkey_c(pub []byte) (*icrypto.PublicKey, error) {
x, y := elliptic.Unmarshal(sm2.P256Sm2(), pub)
if x == nil {
return nil, errInvalidSm2Pubkey
}
return &icrypto.PublicKey{Curve: sm2.P256Sm2(), X: x, Y: y}, nil
}
//sm2加密抽象
type SmCrypto struct {
}
// Keccak256 calculates and returns the Keccak256 hash of the input data.
func (e *SmCrypto) X256(data ...[]byte) []byte {
s := sm3.New()
for _, b := range data {
s.Write(b)
}
return s.Sum(nil)
}
// Keccak256Hash calculates and returns the Keccak256 hash of the input data,
// converting it to an internal Hash data structure.
func (e *SmCrypto) X256Hash(data ...[]byte) (h common.Hash) {
s := sm3.New()
for _, b := range data {
s.Write(b)
}
s.Sum(h[:0])
return h
}
// Keccak512 calculates and returns the Keccak512 hash of the input data.
func (e *SmCrypto) X512(data ...[]byte) []byte {
//d := sha3.NewLegacyKeccak512()
//for _, b := range data {
// d.Write(b)
//}
//return d.Sum(nil)
return nil
}
// CreateAddress creates an ethereum address given the bytes and the nonce
func (e *SmCrypto) CreateAddress(b common.Address, nonce uint64) common.Address {
data, _ := rlp.EncodeToBytes([]interface{}{b, nonce})
return common.BytesToAddress(e.X256(data)[12:])
}
// CreateAddress2 creates an ethereum address given the address bytes, initial
// contract code hash and a salt.
func (e *SmCrypto) CreateAddress2(b common.Address, salt [32]byte, inithash []byte) common.Address {
return common.BytesToAddress(e.X256([]byte{0xff}, b.Bytes(), salt[:], inithash)[12:])
}
func (e *SmCrypto) ToPriKey(d []byte) (*icrypto.PrivateKey, error) {
return e.ToSm2(d)
}
// ToECDSA creates a private key with the given D value.
func (e *SmCrypto) ToSm2(d []byte) (*icrypto.PrivateKey, error) {
return toSm2(d, true)
}
func (e *SmCrypto) ToPriKeyUnsafe(d []byte) *icrypto.PrivateKey {
return e.ToSm2Unsafe(d)
}
// ToECDSAUnsafe blindly converts a binary blob to a private key. It should almost
// never be used unless you are sure the input is valid and want to avoid hitting
// errors due to bad origin encoding (0 prefixes cut off).
func (e *SmCrypto) ToSm2Unsafe(d []byte) *icrypto.PrivateKey {
priv, _ := toSm2(d, false)
return priv
}
// toECDSA creates a private key with the given D value. The strict parameter
// controls whether the key's length should be enforced at the curve size or
// it can also accept legacy encodings (0 prefixes).
func toSm2(d []byte, strict bool) (*icrypto.PrivateKey, error) {
priv := new(sm2.PrivateKey)
priv.PublicKey.Curve = sm2.P256Sm2()
if strict && 8*len(d) != priv.Params().BitSize {
return nil, fmt.Errorf("invalid length, need %d bits", priv.Params().BitSize)
}
priv.D = new(big.Int).SetBytes(d)
// The priv.D must < N
//if priv.D.Cmp(secp256k1N) >= 0 {
// return nil, fmt.Errorf("invalid private key, >=N")
//}
// The priv.D must not be zero or negative.
if priv.D.Sign() <= 0 {
return nil, fmt.Errorf("invalid private key, zero or negative")
}
priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(d)
if priv.PublicKey.X == nil {
return nil, errors.New("invalid private key")
}
//需要赋值转换为接口定义的私钥形式
return &icrypto.PrivateKey{
D: priv.D,
PublicKey: icrypto.PublicKey{
Curve: priv.Curve,
X: priv.X,
Y: priv.Y,
},
}, nil
}
func (e *SmCrypto) FromPriKey(priv *icrypto.PrivateKey) []byte {
return e.FromSm2(priv)
}
// FromECDSA exports a private key into a binary dump.
func (e *SmCrypto) FromSm2(priv *icrypto.PrivateKey) []byte {
if priv == nil {
return nil
}
return math.PaddedBigBytes(priv.D, priv.Params().BitSize/8)
}
// UnmarshalPubkey converts bytes to a secp256k1 public key.
func (e *SmCrypto) UnmarshalPubkey(pub []byte) (*icrypto.PublicKey, error) {
x, y := elliptic.Unmarshal(sm2.P256Sm2(), pub)
if x == nil {
return nil, errInvalidSm2Pubkey
}
return &icrypto.PublicKey{Curve: sm2.P256Sm2(), X: x, Y: y}, nil
}
func (e *SmCrypto) FromPub(pub *icrypto.PublicKey) []byte {
return e.FromSM2Pub(pub)
}
func (e *SmCrypto) FromSM2Pub(pub *icrypto.PublicKey) []byte {
if pub == nil || pub.X == nil || pub.Y == nil {
return nil
}
return elliptic.Marshal(sm2.P256Sm2(), pub.X, pub.Y)
}
func (e *SmCrypto) HexToPriKey(hexkey string) (*icrypto.PrivateKey, error) {
return e.HexToSm2(hexkey)
}
// HexToECDSA parses a secp256k1 private key.
func (e *SmCrypto) HexToSm2(hexkey string) (*icrypto.PrivateKey, error) {
b, err := hex.DecodeString(hexkey)
if err != nil {
return nil, errors.New("invalid hex string")
}
return e.ToSm2(b)
}
func (e *SmCrypto) LoadPriKey(file string) (*icrypto.PrivateKey, error) {
return e.LoadSm2(file)
}
// LoadECDSA loads a secp256k1 private key from the given file.
func (e *SmCrypto) LoadSm2(file string) (*icrypto.PrivateKey, error) {
buf := make([]byte, 64)
fd, err := os.Open(file)
if err != nil {
return nil, err
}
defer fd.Close()
if _, err := io.ReadFull(fd, buf); err != nil {
return nil, err
}
key, err := hex.DecodeString(string(buf))
if err != nil {
return nil, err
}
return e.ToSm2(key)
}
func (e *SmCrypto) SavePriKey(file string, key *icrypto.PrivateKey) error {
return e.SaveSm2(file, key)
}
// SaveECDSA saves a secp256k1 private key to the given file with
// restrictive permissions. The key data is saved hex-encoded.
func (e *SmCrypto) SaveSm2(file string, key *icrypto.PrivateKey) error {
k := hex.EncodeToString(e.FromSm2(key))
return ioutil.WriteFile(file, []byte(k), 0600)
}
func (e *SmCrypto) GenerateKey() (*icrypto.PrivateKey, error) {
eprk, err := sm2.GenerateKey()
return &icrypto.PrivateKey{
PublicKey: icrypto.PublicKey{
Curve: eprk.Curve,
X: eprk.X,
Y: eprk.Y,
},
D: eprk.D,
}, err
}
func (e *SmCrypto) GenerateKey2(rand io.Reader) (*icrypto.PrivateKey, error) {
eprk, err := sm2.GenerateKey2(rand)
return &icrypto.PrivateKey{
PublicKey: icrypto.PublicKey{
Curve: eprk.Curve,
X: eprk.X,
Y: eprk.Y,
},
D: eprk.D,
}, err
}
// ValidateSignatureValues verifies whether the signature values are valid with
// the given chain rules. The v value is assumed to be either 0 or 1.
func (e *SmCrypto) ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
//if r.Cmp(common.Big1) < 0 || s.Cmp(common.Big1) < 0 {
// return false
//}
// reject upper range of s values (ECDSA malleability)
// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
//if homestead && s.Cmp(secp256k1halfN) > 0 {
// return false
//}
// Frontier: allow s to be in full N range
//return r.Cmp(secp256k1N) < 0 && s.Cmp(secp256k1N) < 0 && (v == 0 || v == 1)
return true
}
func (e *SmCrypto) PubkeyToAddress(p *icrypto.PublicKey) common.Address {
pubBytes := e.FromSM2Pub(p)
return common.BytesToAddress(e.X256(pubBytes[1:])[12:])
}
func zeroBytes(bytes []byte) {
for i := range bytes {
bytes[i] = 0
}
}
// Ecrecover returns the uncompressed public key that created the given signature.
func (e *SmCrypto) Ecrecover(pub, hash, sig []byte) ([]byte, error) {
pk, err := e.UnmarshalPubkey(pub)
if err != nil {
return nil, errors.New("sm2 Ecrecover-UnmarshalPubkey err")
}
if sm2.VerifySign(&sm2.PublicKey{Curve: pk.Curve, X: pk.X, Y: pk.Y}, hash, sig) {
return pub, nil
}
return nil, errors.New("sm2 Ecrecover-VerifySign err")
}
// SigToPub returns the public key that created the given signature.
func (e *SmCrypto) SigToPub(pub, hash, sig []byte) (*icrypto.PublicKey, error) {
s, err := e.Ecrecover(pub, hash, sig)
if err != nil {
return nil, err
}
x, y := elliptic.Unmarshal(sm2.P256Sm2(), s)
return &icrypto.PublicKey{Curve: sm2.P256Sm2(), X: x, Y: y}, nil
}
// Sign calculates an ECDSA signature.
//
// This function is susceptible to chosen plaintext attacks that can leak
// information about the private key that is used for signing. Callers must
// be aware that the given hash cannot be chosen by an adversery. Common
// solution is to hash any input before calculating the signature.
//
// The produced signature is in the [R || S || V] format where V is 0 or 1.
func (e *SmCrypto) Sign(hash []byte, prv *icrypto.PrivateKey) (sig []byte, err error) {
if len(hash) != 32 {
return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash))
}
return sm2.SM2Sign(&sm2.PrivateKey{
PublicKey: sm2.PublicKey{Curve: prv.Curve, X: prv.X, Y: prv.Y},
D: prv.D,
}, hash)
}
// VerifySignature checks that the given public key created signature over hash.
// The public key should be in compressed (33 bytes) or uncompressed (65 bytes) format.
// The signature should have the 64 byte [R || S] format.
func (e *SmCrypto) VerifySignature(pubkey, hash, signature []byte) bool {
pub, err := e.UnmarshalPubkey(pubkey)
if err != nil {
return false
}
if sm2.VerifySign(&sm2.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}, hash, signature) {
return true
}
return false
}
// DecompressPubkey parses a public key in the 33-byte compressed format.
func (e *SmCrypto) DecompressPubkey(pubkey []byte) (*icrypto.PublicKey, error) {
pk := sm2.Decompress(pubkey)
return &icrypto.PublicKey{Curve: pk.Curve, X: pk.X, Y: pk.Y}, nil
}
// CompressPubkey encodes a public key to the 33-byte compressed format.
func (e *SmCrypto) CompressPubkey(pubkey *icrypto.PublicKey) []byte {
return sm2.Compress(&sm2.PublicKey{Curve: pubkey.Curve, X: pubkey.X, Y: pubkey.Y})
}
// S256 returns an instance of the secp256k1 curve.
func (e *SmCrypto) S256() elliptic.Curve {
return sm2.P256Sm2()
}
...@@ -28,9 +28,7 @@ import ( ...@@ -28,9 +28,7 @@ import (
"errors" "errors"
"io" "io"
"math/big" "math/big"
"github.com/coupons/sm_crypto/sm3"
"github.com/TMChain/go-TMChain_test/crypto/crypto_interface"
"github.com/chaincodecert/sm_crypto/sm3"
) )
const ( const (
...@@ -52,13 +50,13 @@ func (priv *PrivateKey) Public() crypto.PublicKey { ...@@ -52,13 +50,13 @@ func (priv *PrivateKey) Public() crypto.PublicKey {
return &priv.PublicKey return &priv.PublicKey
} }
// sign format = 30 + len(z) + 02 + len(r) + r + 02 + len(s) + s, z being what follows its size, ie 02+len(r)+r+02+len(s)+s /// sign format = 30 + len(z) + 02 + len(r) + r + 02 + len(s) + s, z being what follows its size, ie 02+len(r)+r+02+len(s)+s
func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) { func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
r, s, err := Sign(priv, msg) r, s, err := Sign(priv, msg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sig := icrypto.FormatSm2SigTo64(r, s) sig := FormatSm2SigTo64(r, s)
return sig, nil return sig, nil
} }
...@@ -67,7 +65,7 @@ func SM2Sign(priv *PrivateKey, hash []byte) ([]byte, error) { ...@@ -67,7 +65,7 @@ func SM2Sign(priv *PrivateKey, hash []byte) ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
sig := icrypto.FormatSm2SigTo64(r, s) sig := FormatSm2SigTo64(r, s)
return sig, nil return sig, nil
} }
...@@ -445,3 +443,32 @@ func (z *zr) Read(dst []byte) (n int, err error) { ...@@ -445,3 +443,32 @@ func (z *zr) Read(dst []byte) (n int, err error) {
} }
var zeroReader = &zr{} var zeroReader = &zr{}
func FormatSm2SigTo64(r, s *big.Int) []byte {
R := r.Bytes()
S := s.Bytes()
var zeroInsertR []byte
for i := 0; i < 32-len(R); i++ {
zeroInsertR = append(zeroInsertR, byte(0))
}
R = insertByteSliceCopy(R, zeroInsertR, 0)
var zeroInsertS []byte
for i := 0; i < 32-len(S); i++ {
zeroInsertS = append(zeroInsertS, byte(0))
}
S = insertByteSliceCopy(S, zeroInsertS, 0)
sig := make([]byte, 64)
copy(sig[:32], R[:])
copy(sig[32:], S[:])
return sig
}
func insertByteSliceCopy(slice, insertion []byte, index int) []byte {
result := make([]byte, len(slice)+len(insertion))
at := copy(result, slice[:index])
at += copy(result[at:], insertion)
copy(result[at:], slice[index:])
return result
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment