diff --git a/README.md b/README.md index 8185e6c580..6fe4a21edf 100644 --- a/README.md +++ b/README.md @@ -20,18 +20,6 @@ Although it was primarily written for btcd, this package has intentionally been designed so it can be used as a standalone package for any projects needing to use secp256k1 elliptic curve cryptography. -## Sample Use - -```Go - import crypto/ecdsa - - pubKey, err := btcec.ParsePubKey(pkStr, btcec.S256()) - - signature, err := btcec.ParseSignature(sigStr, btcec.S256()) - - ok := ecdsa.Verify(pubKey, message, signature.R, signature.S) -``` - ## Documentation [![GoDoc](https://godoc.org/github.com/conformal/btcec?status.png)] @@ -51,6 +39,18 @@ http://localhost:6060/pkg/github.com/conformal/btcec $ go get github.com/conformal/btcec ``` +## Examples + +* [Sign Message] + (http://godoc.org/github.com/conformal/btcec#example-package--SignMessage) + Demonstrates signing a message with a secp256k1 private key that is first + parsed form raw bytes and serializing the generated signature. + +* [Verify Signature] + (http://godoc.org/github.com/conformal/btcec#example-package--verifySignature) + Demonstrates verifying a secp256k1 signature against a public key that is + first parsed from raw bytes. The signature is also parsed from raw bytes. + ## GPG Verification Key All official release tags are signed by Conformal so users can ensure the code diff --git a/doc.go b/doc.go index 90f2b90e34..76ac472370 100644 --- a/doc.go +++ b/doc.go @@ -15,88 +15,7 @@ crypto/elliptic Curve interface in order to permit using these curves with the standard crypto/ecdsa package provided with go. Helper functionality is provided to parse signatures and public keys from standard formats. It was designed for use with btcd, but should be -general enough for other uses of elliptic curve crypto. It was based on -some initial work by ThePiachu. - -Usage - -To verify a secp256k1 signature, the following may be done: - - package main - - import ( - "encoding/hex" - "github.com/conformal/btcec" - "github.com/conformal/btcwire" - "log" - ) - - 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) - } - - // 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") - } - } +general enough for other uses of elliptic curve crypto. It was originally based +on some initial work by ThePiachu, but has significantly diverged since then. */ package btcec diff --git a/example_test.go b/example_test.go new file mode 100644 index 0000000000..302e7c59e1 --- /dev/null +++ b/example_test.go @@ -0,0 +1,89 @@ +// Copyright (c) 2014 Conformal Systems LLC. +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcec_test + +import ( + "encoding/hex" + "fmt" + + "github.com/conformal/btcec" + "github.com/conformal/btcwire" +) + +// This example demonstrates signing a message with a secp256k1 private key that +// is first parsed form raw bytes and serializing the generated signature. +func Example_signMessage() { + // Decode a hex-encoded private key. + pkBytes, err := hex.DecodeString("22a47fa09a223f2aa079edf85a7c2d4f87" + + "20ee63e502ee2869afab7de234b80c") + if err != nil { + fmt.Println(err) + return + } + privKey, pubKey := btcec.PrivKeyFromBytes(btcec.S256(), pkBytes) + + // Sign a message using the private key. + message := "test message" + messageHash := btcwire.DoubleSha256([]byte(message)) + signature, err := privKey.Sign(messageHash) + if err != nil { + fmt.Println(err) + return + } + + // Serialize and display the signature. + // + // NOTE: This is commented out for the example since the signature + // produced uses random numbers and therefore will always be different. + //fmt.Printf("Serialized Signature: %x\n", signature.Serialize()) + + // Verify the signature for the message using the public key. + verified := signature.Verify(messageHash, pubKey) + fmt.Printf("Signature Verified? %v\n", verified) + + // Output: + // Signature Verified? true +} + +// This example demonstrates verifying a secp256k1 signature against a public +// key that is first parsed from raw bytes. The signature is also parsed from +// raw bytes. +func Example_verifySignature() { + // Decode hex-encoded serialized public key. + pubKeyBytes, err := hex.DecodeString("02a673638cb9587cb68ea08dbef685c" + + "6f2d2a751a8b3c6f2a7e9a4999e6e4bfaf5") + if err != nil { + fmt.Println(err) + return + } + pubKey, err := btcec.ParsePubKey(pubKeyBytes, btcec.S256()) + if err != nil { + fmt.Println(err) + return + } + + // Decode hex-encoded serialized signature. + sigBytes, err := hex.DecodeString("30450220090ebfb3690a0ff115bb1b38b" + + "8b323a667b7653454f1bccb06d4bbdca42c2079022100ec95778b51e707" + + "1cb1205f8bde9af6592fc978b0452dafe599481c46d6b2e479") + if err != nil { + fmt.Println(err) + return + } + signature, err := btcec.ParseSignature(sigBytes, btcec.S256()) + if err != nil { + fmt.Println(err) + return + } + + // Verify the signature for the message using the public key. + message := "test message" + messageHash := btcwire.DoubleSha256([]byte(message)) + verified := signature.Verify(messageHash, pubKey) + fmt.Println("Signature Verified?", verified) + + // Output: + // Signature Verified? true +}