diff options
author | Felix Lange <fjl@users.noreply.github.com> | 2017-02-18 16:24:12 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2017-02-18 16:24:12 +0800 |
commit | 9b0af513867fad4aeb3516e4711dd0ea4f5bc90c (patch) | |
tree | b37d808d57873c6aec550431534e26602dfd0475 /crypto/signature_nocgo.go | |
parent | bf21549faa7de6e2b920855468b14856c6f503c4 (diff) | |
download | go-tangerine-9b0af513867fad4aeb3516e4711dd0ea4f5bc90c.tar.gz go-tangerine-9b0af513867fad4aeb3516e4711dd0ea4f5bc90c.tar.zst go-tangerine-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/signature_nocgo.go')
-rw-r--r-- | crypto/signature_nocgo.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go new file mode 100644 index 000000000..47880aaf4 --- /dev/null +++ b/crypto/signature_nocgo.go @@ -0,0 +1,77 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +// +build nacl js nocgo + +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "fmt" + + "github.com/btcsuite/btcd/btcec" +) + +func Ecrecover(hash, sig []byte) ([]byte, error) { + pub, err := SigToPub(hash, sig) + if err != nil { + return nil, err + } + bytes := (*btcec.PublicKey)(pub).SerializeUncompressed() + return bytes, err +} + +func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { + // Convert to btcec input format with 'recovery id' v at the beginning. + btcsig := make([]byte, 65) + btcsig[0] = sig[64] + 27 + copy(btcsig[1:], sig) + + pub, _, err := btcec.RecoverCompact(btcec.S256(), btcsig, hash) + return (*ecdsa.PublicKey)(pub), err +} + +// 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(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { + if len(hash) != 32 { + return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) + } + if prv.Curve != btcec.S256() { + return nil, fmt.Errorf("private key curve is not secp256k1") + } + sig, err := btcec.SignCompact(btcec.S256(), (*btcec.PrivateKey)(prv), hash, false) + if err != nil { + return nil, err + } + // Convert to Ethereum signature format with 'recovery id' v at the end. + v := sig[0] - 27 + copy(sig, sig[1:]) + sig[64] = v + return sig, nil +} + +// S256 returns an instance of the secp256k1 curve. +func S256() elliptic.Curve { + return btcec.S256() +} |