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:
Dave Collins 2014-05-19 23:21:39 -05:00
parent af82a73fe4
commit 77c02f36ee
6 changed files with 93 additions and 27 deletions

78
doc.go
View file

@ -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

View file

@ -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
} }

View file

@ -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)
}

View file

@ -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
} }

View file

@ -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.

View file

@ -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)