aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/crypto.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@users.noreply.github.com>2017-02-18 16:24:12 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2017-02-18 16:24:12 +0800
commit9b0af513867fad4aeb3516e4711dd0ea4f5bc90c (patch)
treeb37d808d57873c6aec550431534e26602dfd0475 /crypto/crypto.go
parentbf21549faa7de6e2b920855468b14856c6f503c4 (diff)
downloaddexon-9b0af513867fad4aeb3516e4711dd0ea4f5bc90c.tar.gz
dexon-9b0af513867fad4aeb3516e4711dd0ea4f5bc90c.tar.zst
dexon-9b0af513867fad4aeb3516e4711dd0ea4f5bc90c.zip
crypto: add btcec fallback for sign/recover without cgo (#3680)
* vendor: add github.com/btcsuite/btcd/btcec * crypto: add btcec fallback for sign/recover without cgo This commit adds a non-cgo fallback implementation of secp256k1 operations. * crypto, core/vm: remove wrappers for sha256, ripemd160
Diffstat (limited to 'crypto/crypto.go')
-rw-r--r--crypto/crypto.go95
1 files changed, 16 insertions, 79 deletions
diff --git a/crypto/crypto.go b/crypto/crypto.go
index ce45ebd38..9d67d82e1 100644
--- a/crypto/crypto.go
+++ b/crypto/crypto.go
@@ -20,22 +20,21 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
- "crypto/sha256"
- "fmt"
+ "encoding/hex"
+ "errors"
"io"
"io/ioutil"
"math/big"
"os"
- "encoding/hex"
- "errors"
-
"github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/crypto/ecies"
- "github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/ethereum/go-ethereum/crypto/sha3"
"github.com/ethereum/go-ethereum/rlp"
- "golang.org/x/crypto/ripemd160"
+)
+
+var (
+ secp256k1_N, _ = new(big.Int).SetString("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", 16)
+ secp256k1_halfN = new(big.Int).Div(secp256k1_N, big.NewInt(2))
)
func Keccak256(data ...[]byte) []byte {
@@ -56,7 +55,6 @@ func Keccak256Hash(data ...[]byte) (h common.Hash) {
}
// Deprecated: For backward compatibility as other packages depend on these
-func Sha3(data ...[]byte) []byte { return Keccak256(data...) }
func Sha3Hash(data ...[]byte) common.Hash { return Keccak256Hash(data...) }
// Creates an ethereum address given the bytes and the nonce
@@ -65,39 +63,16 @@ func CreateAddress(b common.Address, nonce uint64) common.Address {
return common.BytesToAddress(Keccak256(data)[12:])
}
-func Sha256(data []byte) []byte {
- hash := sha256.Sum256(data)
-
- return hash[:]
-}
-
-func Ripemd160(data []byte) []byte {
- ripemd := ripemd160.New()
- ripemd.Write(data)
-
- return ripemd.Sum(nil)
-}
-
-// Ecrecover returns the public key for the private key that was used to
-// calculate the signature.
-//
-// Note: secp256k1 expects the recover id to be either 0, 1. Ethereum
-// signatures have a recover id with an offset of 27. Callers must take
-// this into account and if "recovering" from an Ethereum signature adjust.
-func Ecrecover(hash, sig []byte) ([]byte, error) {
- return secp256k1.RecoverPubkey(hash, sig)
-}
-
-// New methods using proper ecdsa keys from the stdlib
+// ToECDSA creates a private key with the given D value.
func ToECDSA(prv []byte) *ecdsa.PrivateKey {
if len(prv) == 0 {
return nil
}
priv := new(ecdsa.PrivateKey)
- priv.PublicKey.Curve = secp256k1.S256()
+ priv.PublicKey.Curve = S256()
priv.D = common.BigD(prv)
- priv.PublicKey.X, priv.PublicKey.Y = secp256k1.S256().ScalarBaseMult(prv)
+ priv.PublicKey.X, priv.PublicKey.Y = priv.PublicKey.Curve.ScalarBaseMult(prv)
return priv
}
@@ -112,15 +87,15 @@ func ToECDSAPub(pub []byte) *ecdsa.PublicKey {
if len(pub) == 0 {
return nil
}
- x, y := elliptic.Unmarshal(secp256k1.S256(), pub)
- return &ecdsa.PublicKey{Curve: secp256k1.S256(), X: x, Y: y}
+ x, y := elliptic.Unmarshal(S256(), pub)
+ return &ecdsa.PublicKey{Curve: S256(), X: x, Y: y}
}
func FromECDSAPub(pub *ecdsa.PublicKey) []byte {
if pub == nil || pub.X == nil || pub.Y == nil {
return nil
}
- return elliptic.Marshal(secp256k1.S256(), pub.X, pub.Y)
+ return elliptic.Marshal(S256(), pub.X, pub.Y)
}
// HexToECDSA parses a secp256k1 private key.
@@ -164,7 +139,7 @@ func SaveECDSA(file string, key *ecdsa.PrivateKey) error {
}
func GenerateKey() (*ecdsa.PrivateKey, error) {
- return ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
+ return ecdsa.GenerateKey(S256(), rand.Reader)
}
// ValidateSignatureValues verifies whether the signature values are valid with
@@ -175,49 +150,11 @@ func ValidateSignatureValues(v byte, r, s *big.Int, homestead bool) bool {
}
// reject upper range of s values (ECDSA malleability)
// see discussion in secp256k1/libsecp256k1/include/secp256k1.h
- if homestead && s.Cmp(secp256k1.HalfN) > 0 {
+ if homestead && s.Cmp(secp256k1_halfN) > 0 {
return false
}
// Frontier: allow s to be in full N range
- return r.Cmp(secp256k1.N) < 0 && s.Cmp(secp256k1.N) < 0 && (v == 0 || v == 1)
-}
-
-func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) {
- s, err := Ecrecover(hash, sig)
- if err != nil {
- return nil, err
- }
-
- x, y := elliptic.Unmarshal(secp256k1.S256(), s)
- return &ecdsa.PublicKey{Curve: secp256k1.S256(), 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 Sign(data []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) {
- if len(data) != 32 {
- return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(data))
- }
-
- seckey := common.LeftPadBytes(prv.D.Bytes(), prv.Params().BitSize/8)
- defer zeroBytes(seckey)
- sig, err = secp256k1.Sign(data, seckey)
- return
-}
-
-func Encrypt(pub *ecdsa.PublicKey, message []byte) ([]byte, error) {
- return ecies.Encrypt(rand.Reader, ecies.ImportECDSAPublic(pub), message, nil, nil)
-}
-
-func Decrypt(prv *ecdsa.PrivateKey, ct []byte) ([]byte, error) {
- key := ecies.ImportECDSA(prv)
- return key.Decrypt(rand.Reader, ct, nil, nil)
+ return r.Cmp(secp256k1_N) < 0 && s.Cmp(secp256k1_N) < 0 && (v == 0 || v == 1)
}
func PubkeyToAddress(p ecdsa.PublicKey) common.Address {