Cleanup new code introduced by Pull Request #4.
- Keep comments to 80 cols for consistency with the rest of the code base - Made verify a method off of Signature instead of PublicKey since one verifies a signature with a public key as opposed to the other way around - Return new signature from Sign function directly rather than creating a local temporary variable - Modify a couple of comments as recommended by @owainga - Update sample usage in doc.go for both signing messages and verifying signatures ok @owainga
This commit is contained in:
parent
af82a73fe4
commit
77c02f36ee
6 changed files with 93 additions and 27 deletions
78
doc.go
78
doc.go
|
@ -20,15 +20,83 @@ some initial work by ThePiachu.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
|
|
||||||
To verify a secp256k1 signature the following may be done:
|
To verify a secp256k1 signature, the following may be done:
|
||||||
|
|
||||||
import crypto/ecdsa
|
package main
|
||||||
|
|
||||||
pubKey, err := btcec.ParsePubKey(pkStr, btcec.S256())
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"github.com/conformal/btcec"
|
||||||
|
"github.com/conformal/btcwire"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
signature, err := btcec.ParseSignature(sigStr, btcec.S256())
|
func main() {
|
||||||
|
// Decode hex-encoded serialized public key.
|
||||||
|
pubKeyBytes, err := hex.DecodeString("02a673638cb9587cb68ea08dbef685c"+
|
||||||
|
"6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
ok := ecdsa.Verify(pubKey, message, signature.R, signature.S)
|
// Decode hex-encoded serialized signature.
|
||||||
|
sigBytes, err := hex.DecodeString("30450220090ebfb3690a0ff115bb1b38b"+
|
||||||
|
"8b323a667b7653454f1bccb06d4bbdca42c2079022100ec95778b51e707"+
|
||||||
|
"1cb1205f8bde9af6592fc978b0452dafe599481c46d6b2e479")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
decodedSig, err := btcec.ParseSignature(sigBytes, btcec.S256())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the signature for the message using the public key.
|
||||||
|
message := "test message"
|
||||||
|
messageHash := btcwire.DoubleSha256([]byte(message))
|
||||||
|
if decodedSig.Verify(messageHash, pubKey) {
|
||||||
|
log.Println("Signature Verified")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
To sign a message using a secp256k1 private key, the following may be done:
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"github.com/conformal/btcec"
|
||||||
|
"github.com/conformal/btcwire"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Decode a hex-encoded private key.
|
||||||
|
pkBytes, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2d4f87"+
|
||||||
|
"20ee63e502ee2869afab7de234b80c")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
priv, pub := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes)
|
||||||
|
|
||||||
|
// Sign a message using the private key.
|
||||||
|
message := "test message"
|
||||||
|
messageHash := btcwire.DoubleSha256([]byte(message))
|
||||||
|
sig, err := priv.Sign(messageHash)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Serialized Signature: %x\n", sig.Serialize())
|
||||||
|
|
||||||
|
// Verify the signature for the message using the public key.
|
||||||
|
if sig.Verify(messageHash, pub) {
|
||||||
|
log.Println("Signature Verified")
|
||||||
|
}
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
package btcec
|
package btcec
|
||||||
|
|
15
privkey.go
15
privkey.go
|
@ -10,8 +10,9 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrivateKey is an ecdsa.PrivateKey
|
// PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing
|
||||||
// It provides a method Sign
|
// things with the the private key without having to directly import the ecdsa
|
||||||
|
// package.
|
||||||
type PrivateKey ecdsa.PrivateKey
|
type PrivateKey ecdsa.PrivateKey
|
||||||
|
|
||||||
// PrivKeyFromBytes returns a private and public key for `curve' based on the
|
// PrivKeyFromBytes returns a private and public key for `curve' based on the
|
||||||
|
@ -37,16 +38,12 @@ func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey {
|
||||||
return (*ecdsa.PrivateKey)(p)
|
return (*ecdsa.PrivateKey)(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign wraps ecdsa.Sign to sign an arbitrary length hash (which should be the result of hashing a larger message) using the private key.
|
// Sign wraps ecdsa.Sign to sign the provided hash (which should be the result
|
||||||
// It returns the signature as a *Signature. The security of the private key depends on the entropy of rand (crypto/rand.Reader).
|
// of hashing a larger message) using the private key.
|
||||||
func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {
|
func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {
|
||||||
r, s, err := ecdsa.Sign(rand.Reader, p.ToECDSA(), hash)
|
r, s, err := ecdsa.Sign(rand.Reader, p.ToECDSA(), hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sig := &Signature{
|
return &Signature{R: r, S: s}, nil
|
||||||
R: r,
|
|
||||||
S: s,
|
|
||||||
}
|
|
||||||
return sig, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,9 +162,3 @@ func paddedAppend(size uint, dst, src []byte) []byte {
|
||||||
}
|
}
|
||||||
return append(dst, src...)
|
return append(dst, src...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify calls ecdsa.Verify to verify the signature of hash using the public key.
|
|
||||||
// Its return value records whether the signature is valid.
|
|
||||||
func (p *PublicKey) Verify(hash []byte, sig *Signature) bool {
|
|
||||||
return ecdsa.Verify(p.ToECDSA(), hash, sig.R, sig.S)
|
|
||||||
}
|
|
||||||
|
|
|
@ -235,7 +235,7 @@ func TestPrivKeys(t *testing.T) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if !pub.Verify(hash, sig) {
|
if !sig.Verify(hash, pub) {
|
||||||
t.Errorf("%s could not verify: %v", test.name, err)
|
t.Errorf("%s could not verify: %v", test.name, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,12 @@ func (sig *Signature) Serialize() []byte {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify calls ecdsa.Verify to verify the signature of hash using the public
|
||||||
|
// key. It returns true if the signature is valid, false otherwise.
|
||||||
|
func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
|
||||||
|
return ecdsa.Verify(pubKey.ToECDSA(), hash, sig.R, sig.S)
|
||||||
|
}
|
||||||
|
|
||||||
func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) {
|
func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) {
|
||||||
// Originally this code used encoding/asn1 in order to parse the
|
// Originally this code used encoding/asn1 in order to parse the
|
||||||
// signature, but a number of problems were found with this approach.
|
// signature, but a number of problems were found with this approach.
|
||||||
|
|
|
@ -54,16 +54,17 @@ github.com/conformal/btcec/field.go fieldVal.Mul 100.00% (1/1)
|
||||||
github.com/conformal/btcec/field.go fieldVal.Square 100.00% (1/1)
|
github.com/conformal/btcec/field.go fieldVal.Square 100.00% (1/1)
|
||||||
github.com/conformal/btcec/privkey.go PrivateKey.ToECDSA 100.00% (1/1)
|
github.com/conformal/btcec/privkey.go PrivateKey.ToECDSA 100.00% (1/1)
|
||||||
github.com/conformal/btcec/pubkey.go isOdd 100.00% (1/1)
|
github.com/conformal/btcec/pubkey.go isOdd 100.00% (1/1)
|
||||||
github.com/conformal/btcec/pubkey.go PublicKey.ToECDSA 100.00% (1/1)
|
github.com/conformal/btcec/signature.go Signature.Verify 100.00% (1/1)
|
||||||
github.com/conformal/btcec/pubkey.go PublicKey.Verify 100.00% (1/1)
|
|
||||||
github.com/conformal/btcec/signature.go ParseSignature 100.00% (1/1)
|
github.com/conformal/btcec/signature.go ParseSignature 100.00% (1/1)
|
||||||
github.com/conformal/btcec/signature.go ParseDERSignature 100.00% (1/1)
|
github.com/conformal/btcec/signature.go ParseDERSignature 100.00% (1/1)
|
||||||
|
github.com/conformal/btcec/pubkey.go PublicKey.ToECDSA 100.00% (1/1)
|
||||||
github.com/conformal/btcec/pubkey.go ParsePubKey 92.86% (26/28)
|
github.com/conformal/btcec/pubkey.go ParsePubKey 92.86% (26/28)
|
||||||
|
github.com/conformal/btcec/signature.go SignCompact 90.91% (20/22)
|
||||||
github.com/conformal/btcec/pubkey.go decompressPoint 88.89% (8/9)
|
github.com/conformal/btcec/pubkey.go decompressPoint 88.89% (8/9)
|
||||||
github.com/conformal/btcec/signature.go recoverKeyFromSignature 86.96% (20/23)
|
github.com/conformal/btcec/signature.go recoverKeyFromSignature 86.96% (20/23)
|
||||||
github.com/conformal/btcec/signature.go SignCompact 81.82% (18/22)
|
|
||||||
github.com/conformal/btcec/privkey.go PrivateKey.Sign 80.00% (4/5)
|
|
||||||
github.com/conformal/btcec/signature.go hashToInt 77.78% (7/9)
|
|
||||||
github.com/conformal/btcec/signature.go RecoverCompact 77.78% (7/9)
|
github.com/conformal/btcec/signature.go RecoverCompact 77.78% (7/9)
|
||||||
github.com/conformal/btcec ------------------------------------- 98.37% (907/922)
|
github.com/conformal/btcec/signature.go hashToInt 77.78% (7/9)
|
||||||
|
github.com/conformal/btcec/privkey.go PrivateKey.Sign 75.00% (3/4)
|
||||||
|
github.com/conformal/btcec/pubkey.go PublicKey.Verify 0.00% (0/1)
|
||||||
|
github.com/conformal/btcec ------------------------------------- 98.48% (908/922)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue