github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/lib/btc/ecdsa.go (about) 1 package btc 2 3 import ( 4 "crypto/rand" 5 "crypto/sha256" 6 "errors" 7 "github.com/piotrnar/gocoin/lib/secp256k1" 8 "math/big" 9 "sync/atomic" 10 ) 11 12 var ( 13 ecdsaVerifyCnt uint64 14 schnorrVerifyCnt uint64 15 checkp2cVerifyCnt uint64 16 17 EC_Verify func(k, s, h []byte) bool 18 Schnorr_Verify func(pkey, sign, msg []byte) bool 19 Check_PayToContract func(m_keydata, base, hash []byte, parity bool) bool 20 ) 21 22 func EcdsaVerifyCnt() uint64 { 23 return atomic.LoadUint64(&ecdsaVerifyCnt) 24 } 25 26 func SchnorrVerifyCnt() uint64 { 27 return atomic.LoadUint64(&schnorrVerifyCnt) 28 } 29 30 func CheckPay2ContractCnt() uint64 { 31 return atomic.LoadUint64(&checkp2cVerifyCnt) 32 } 33 34 func EcdsaVerify(kd []byte, sd []byte, hash []byte) bool { 35 atomic.AddUint64(&ecdsaVerifyCnt, 1) 36 if len(kd) == 0 || len(sd) == 0 { 37 return false 38 } 39 if EC_Verify != nil { 40 return EC_Verify(kd, sd, hash) 41 } 42 return secp256k1.Verify(kd, sd, hash) 43 } 44 45 func EcdsaSign(priv, hash []byte) (r, s *big.Int, err error) { 46 var sig secp256k1.Signature 47 var sec, msg, nonce secp256k1.Number 48 49 sec.SetBytes(priv) 50 msg.SetBytes(hash) 51 52 sha := sha256.New() 53 sha.Write(priv) 54 sha.Write(hash) 55 for { 56 var buf [32]byte 57 rand.Read(buf[:]) 58 sha.Write(buf[:]) 59 nonce.SetBytes(sha.Sum(nil)) 60 if nonce.Sign() > 0 && nonce.Cmp(&secp256k1.TheCurve.Order.Int) < 0 { 61 break 62 } 63 } 64 65 if sig.Sign(&sec, &msg, &nonce, nil) != 1 { 66 err = errors.New("ESCDS Sign error()") 67 } 68 return &sig.R.Int, &sig.S.Int, nil 69 } 70 71 func SchnorrVerify(pkey, sig, msg []byte) bool { 72 atomic.AddUint64(&schnorrVerifyCnt, 1) 73 if Schnorr_Verify != nil { 74 return Schnorr_Verify(pkey, sig, msg) 75 } 76 return secp256k1.SchnorrVerify(pkey, sig, msg) 77 } 78 79 func CheckPayToContract(m_keydata, base, hash []byte, parity bool) bool { 80 atomic.AddUint64(&checkp2cVerifyCnt, 1) 81 if Check_PayToContract != nil { 82 return Check_PayToContract(m_keydata, base, hash, parity) 83 } 84 return secp256k1.CheckPayToContract(m_keydata, base, hash, parity) 85 }