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  }