Add functions to serialize an ecdsa public key.
This commit is contained in:
parent
abfd6b44af
commit
961636c764
5 changed files with 85 additions and 9 deletions
11
internal_test.go
Normal file
11
internal_test.go
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) 2013 Conformal Systems LLC.
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package btcec
|
||||
|
||||
const (
|
||||
TstPubkeyUncompressed = pubkeyUncompressed
|
||||
TstPubkeyCompressed = pubkeyCompressed
|
||||
TstPubkeyHybrid = pubkeyHybrid
|
||||
)
|
43
pubkey.go
43
pubkey.go
|
@ -16,8 +16,8 @@ func isOdd(a *big.Int) bool {
|
|||
|
||||
const (
|
||||
pubkeyCompressed byte = 0x2 // y_bit + x coord
|
||||
pubkeyUncompressed = 0x4 // x coord + y coord
|
||||
pubkeyHybrid = 0x6 // y_bit + x coord + y coord
|
||||
pubkeyUncompressed byte = 0x4 // x coord + y coord
|
||||
pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
|
||||
)
|
||||
|
||||
// ParsePubKey parses a public key for a koblitz curve from a bytestring into a
|
||||
|
@ -88,3 +88,42 @@ func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *ecdsa.PublicKey, e
|
|||
}
|
||||
return &pubkey, nil
|
||||
}
|
||||
|
||||
// PublicKey is an ecdsa.PublicKey with additional functions to
|
||||
// serialize in uncompressed, compressed, and hybrid formats.
|
||||
type PublicKey ecdsa.PublicKey
|
||||
|
||||
// SerializeUncompressed serializes a public key in a 65-byte uncompressed
|
||||
// format.
|
||||
func (p *PublicKey) SerializeUncompressed() []byte {
|
||||
b := make([]byte, 65)
|
||||
b[0] = pubkeyUncompressed
|
||||
copy(b[1:33], p.X.Bytes())
|
||||
copy(b[33:], p.Y.Bytes())
|
||||
return b
|
||||
}
|
||||
|
||||
// SerializeCompressed serializes a public key in a 33-byte compressed format.
|
||||
func (p *PublicKey) SerializeCompressed() []byte {
|
||||
b := make([]byte, 33)
|
||||
format := pubkeyCompressed
|
||||
if isOdd(p.Y) {
|
||||
format |= 0x1
|
||||
}
|
||||
b[0] = format
|
||||
copy(b[1:33], p.X.Bytes())
|
||||
return b
|
||||
}
|
||||
|
||||
// SerializeHybrid serializes a public key in a 65-byte hybrid format.
|
||||
func (p *PublicKey) SerializeHybrid() []byte {
|
||||
b := make([]byte, 65)
|
||||
format := pubkeyHybrid
|
||||
if isOdd(p.Y) {
|
||||
format |= 0x1
|
||||
}
|
||||
b[0] = format
|
||||
copy(b[1:33], p.X.Bytes())
|
||||
copy(b[33:], p.Y.Bytes())
|
||||
return b
|
||||
}
|
||||
|
|
|
@ -5,13 +5,16 @@
|
|||
package btcec_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/conformal/btcec"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type pubKeyTest struct {
|
||||
name string
|
||||
key []byte
|
||||
format byte
|
||||
isValid bool
|
||||
}
|
||||
|
||||
|
@ -30,6 +33,7 @@ var pubKeyTests = []pubKeyTest{
|
|||
0xb4, 0x12, 0xa3,
|
||||
},
|
||||
isValid: true,
|
||||
format: btcec.TstPubkeyUncompressed,
|
||||
},
|
||||
pubKeyTest{
|
||||
name: "uncompressed x changed",
|
||||
|
@ -82,6 +86,7 @@ var pubKeyTests = []pubKeyTest{
|
|||
0xb4, 0x12, 0xa3,
|
||||
},
|
||||
isValid: true,
|
||||
format: btcec.TstPubkeyHybrid,
|
||||
},
|
||||
pubKeyTest{
|
||||
name: "uncompressed as hybrid wrong",
|
||||
|
@ -105,6 +110,7 @@ var pubKeyTests = []pubKeyTest{
|
|||
0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
|
||||
},
|
||||
isValid: true,
|
||||
format: btcec.TstPubkeyCompressed,
|
||||
},
|
||||
// from tx fdeb8e72524e8dab0da507ddbaf5f88fe4a933eb10a66bc4745bb0aa11ea393c
|
||||
pubKeyTest{
|
||||
|
@ -115,6 +121,7 @@ var pubKeyTests = []pubKeyTest{
|
|||
0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
|
||||
},
|
||||
isValid: true,
|
||||
format: btcec.TstPubkeyCompressed,
|
||||
},
|
||||
pubKeyTest{
|
||||
name: "compressed claims uncompressed (ybit = 0)",
|
||||
|
@ -195,7 +202,7 @@ var pubKeyTests = []pubKeyTest{
|
|||
|
||||
func TestPubKeys(t *testing.T) {
|
||||
for _, test := range pubKeyTests {
|
||||
_, err := btcec.ParsePubKey(test.key, btcec.S256())
|
||||
pk, err := btcec.ParsePubKey(test.key, btcec.S256())
|
||||
if err != nil {
|
||||
if test.isValid {
|
||||
t.Errorf("%s pubkey failed when shouldn't %v",
|
||||
|
@ -206,6 +213,22 @@ func TestPubKeys(t *testing.T) {
|
|||
if !test.isValid {
|
||||
t.Errorf("%s counted as valid when it should fail",
|
||||
test.name)
|
||||
continue
|
||||
}
|
||||
var pkStr []byte
|
||||
switch test.format {
|
||||
case btcec.TstPubkeyUncompressed:
|
||||
pkStr = (*btcec.PublicKey)(pk).SerializeUncompressed()
|
||||
case btcec.TstPubkeyCompressed:
|
||||
pkStr = (*btcec.PublicKey)(pk).SerializeCompressed()
|
||||
case btcec.TstPubkeyHybrid:
|
||||
pkStr = (*btcec.PublicKey)(pk).SerializeHybrid()
|
||||
}
|
||||
if !bytes.Equal(test.key, pkStr) {
|
||||
t.Errorf("%s pubkey: serialized keys do not match.",
|
||||
test.name)
|
||||
spew.Dump(test.key)
|
||||
spew.Dump(pkStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ var signatureTests = []signatureTest{
|
|||
|
||||
// This test is now passing (used to be failing) because there
|
||||
// are signatures in the blockchain that have trailing zero
|
||||
// bytes before the hashtype. So ParseSignature was fixed to
|
||||
// bytes before the hashtype. So ParseSignature was fixed to
|
||||
// permit buffers with trailing nonsense after the actual
|
||||
// signature.
|
||||
isValid: true,
|
||||
|
|
|
@ -2,19 +2,22 @@
|
|||
github.com/conformal/btcec/signature.go ParseSignature 100.00% (41/41)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.doubleJacobian 100.00% (21/21)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.ScalarMult 100.00% (9/9)
|
||||
github.com/conformal/btcec/btcec.go initS256 100.00% (7/7)
|
||||
github.com/conformal/btcec/pubkey.go PublicKey.SerializeHybrid 100.00% (8/8)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.IsOnCurve 100.00% (7/7)
|
||||
github.com/conformal/btcec/pubkey.go PublicKey.SerializeCompressed 100.00% (7/7)
|
||||
github.com/conformal/btcec/btcec.go initS256 100.00% (7/7)
|
||||
github.com/conformal/btcec/pubkey.go PublicKey.SerializeUncompressed 100.00% (5/5)
|
||||
github.com/conformal/btcec/btcec.go zForAffine 100.00% (4/4)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.Add 100.00% (3/3)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.QPlus1Div4 100.00% (3/3)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.Add 100.00% (3/3)
|
||||
github.com/conformal/btcec/btcec.go S256 100.00% (2/2)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.Params 100.00% (1/1)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.ScalarBaseMult 100.00% (1/1)
|
||||
github.com/conformal/btcec/btcec.go initAll 100.00% (1/1)
|
||||
github.com/conformal/btcec/pubkey.go isOdd 100.00% (1/1)
|
||||
github.com/conformal/btcec/btcec.go initAll 100.00% (1/1)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.Params 100.00% (1/1)
|
||||
github.com/conformal/btcec/pubkey.go ParsePubKey 96.88% (31/32)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.addJacobian 91.67% (55/60)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.affineFromJacobian 90.00% (9/10)
|
||||
github.com/conformal/btcec/btcec.go KoblitzCurve.Double 0.00% (0/2)
|
||||
github.com/conformal/btcec ------------------------------- 95.61% (196/205)
|
||||
github.com/conformal/btcec ------------------------------- 96.00% (216/225)
|
||||
|
||||
|
|
Loading…
Reference in a new issue