From 9b0af513867fad4aeb3516e4711dd0ea4f5bc90c Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Sat, 18 Feb 2017 09:24:12 +0100 Subject: 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 --- crypto/signature_cgo.go | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 crypto/signature_cgo.go (limited to 'crypto/signature_cgo.go') diff --git a/crypto/signature_cgo.go b/crypto/signature_cgo.go new file mode 100644 index 000000000..5faa6061f --- /dev/null +++ b/crypto/signature_cgo.go @@ -0,0 +1,64 @@ +// 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 . + +// +build !nacl,!js,!nocgo + +package crypto + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto/secp256k1" +) + +func Ecrecover(hash, sig []byte) ([]byte, error) { + return secp256k1.RecoverPubkey(hash, sig) +} + +func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { + s, err := Ecrecover(hash, sig) + if err != nil { + return nil, err + } + + x, y := elliptic.Unmarshal(S256(), s) + return &ecdsa.PublicKey{Curve: 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(hash []byte, prv *ecdsa.PrivateKey) (sig []byte, err error) { + if len(hash) != 32 { + return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) + } + seckey := common.LeftPadBytes(prv.D.Bytes(), prv.Params().BitSize/8) + defer zeroBytes(seckey) + return secp256k1.Sign(hash, seckey) +} + +// S256 returns an instance of the secp256k1 curve. +func S256() elliptic.Curve { + return secp256k1.S256() +} -- cgit