From ac7a367950089af978a398f57010315ff355097e Mon Sep 17 00:00:00 2001 From: Geert-Johan Riemer Date: Thu, 15 May 2014 10:48:52 +0200 Subject: [PATCH] Add type PrivateKey, (*PrivateKey).Sign() and (*PublicKey).Verify(). --- privkey.go | 28 ++++++++++++++++++++++++++-- pubkey.go | 6 ++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/privkey.go b/privkey.go index 8631f222..ad1dfc1f 100644 --- a/privkey.go +++ b/privkey.go @@ -6,12 +6,17 @@ package btcec import ( "crypto/ecdsa" + "crypto/rand" "math/big" ) +// PrivateKey is an ecdsa.PrivateKey +// It provides a method Sign +type PrivateKey ecdsa.PrivateKey + // PrivKeyFromBytes returns a private and public key for `curve' based on the // private key passed as an argument as a byte slice. -func PrivKeyFromBytes(curve *KoblitzCurve, pk []byte) (*ecdsa.PrivateKey, +func PrivKeyFromBytes(curve *KoblitzCurve, pk []byte) (*PrivateKey, *PublicKey) { x, y := curve.ScalarBaseMult(pk) @@ -24,5 +29,24 @@ func PrivKeyFromBytes(curve *KoblitzCurve, pk []byte) (*ecdsa.PrivateKey, D: new(big.Int).SetBytes(pk), } - return priv, (*PublicKey)(&priv.PublicKey) + return (*PrivateKey)(priv), (*PublicKey)(&priv.PublicKey) +} + +// ToECDSA returns the private key as a *ecdsa.PrivateKey. +func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey { + 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. +// It returns the signature as a *Signature. The security of the private key depends on the entropy of rand (crypto/rand.Reader). +func (p *PrivateKey) Sign(hash []byte) (*Signature, error) { + r, s, err := ecdsa.Sign(rand.Reader, p.ToECDSA(), hash) + if err != nil { + return nil, err + } + sig := &Signature{ + R: r, + S: s, + } + return sig, nil } diff --git a/pubkey.go b/pubkey.go index cf0da666..0d7d679d 100644 --- a/pubkey.go +++ b/pubkey.go @@ -162,3 +162,9 @@ func paddedAppend(size uint, dst, src []byte) []byte { } 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) +}