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 (
|
const (
|
||||||
pubkeyCompressed byte = 0x2 // y_bit + x coord
|
pubkeyCompressed byte = 0x2 // y_bit + x coord
|
||||||
pubkeyUncompressed = 0x4 // x coord + y coord
|
pubkeyUncompressed byte = 0x4 // x coord + y coord
|
||||||
pubkeyHybrid = 0x6 // y_bit + 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
|
// 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
|
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
|
package btcec_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"github.com/conformal/btcec"
|
"github.com/conformal/btcec"
|
||||||
|
"github.com/davecgh/go-spew/spew"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type pubKeyTest struct {
|
type pubKeyTest struct {
|
||||||
name string
|
name string
|
||||||
key []byte
|
key []byte
|
||||||
|
format byte
|
||||||
isValid bool
|
isValid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +33,7 @@ var pubKeyTests = []pubKeyTest{
|
||||||
0xb4, 0x12, 0xa3,
|
0xb4, 0x12, 0xa3,
|
||||||
},
|
},
|
||||||
isValid: true,
|
isValid: true,
|
||||||
|
format: btcec.TstPubkeyUncompressed,
|
||||||
},
|
},
|
||||||
pubKeyTest{
|
pubKeyTest{
|
||||||
name: "uncompressed x changed",
|
name: "uncompressed x changed",
|
||||||
|
@ -82,6 +86,7 @@ var pubKeyTests = []pubKeyTest{
|
||||||
0xb4, 0x12, 0xa3,
|
0xb4, 0x12, 0xa3,
|
||||||
},
|
},
|
||||||
isValid: true,
|
isValid: true,
|
||||||
|
format: btcec.TstPubkeyHybrid,
|
||||||
},
|
},
|
||||||
pubKeyTest{
|
pubKeyTest{
|
||||||
name: "uncompressed as hybrid wrong",
|
name: "uncompressed as hybrid wrong",
|
||||||
|
@ -105,6 +110,7 @@ var pubKeyTests = []pubKeyTest{
|
||||||
0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
|
0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
|
||||||
},
|
},
|
||||||
isValid: true,
|
isValid: true,
|
||||||
|
format: btcec.TstPubkeyCompressed,
|
||||||
},
|
},
|
||||||
// from tx fdeb8e72524e8dab0da507ddbaf5f88fe4a933eb10a66bc4745bb0aa11ea393c
|
// from tx fdeb8e72524e8dab0da507ddbaf5f88fe4a933eb10a66bc4745bb0aa11ea393c
|
||||||
pubKeyTest{
|
pubKeyTest{
|
||||||
|
@ -115,6 +121,7 @@ var pubKeyTests = []pubKeyTest{
|
||||||
0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
|
0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
|
||||||
},
|
},
|
||||||
isValid: true,
|
isValid: true,
|
||||||
|
format: btcec.TstPubkeyCompressed,
|
||||||
},
|
},
|
||||||
pubKeyTest{
|
pubKeyTest{
|
||||||
name: "compressed claims uncompressed (ybit = 0)",
|
name: "compressed claims uncompressed (ybit = 0)",
|
||||||
|
@ -195,7 +202,7 @@ var pubKeyTests = []pubKeyTest{
|
||||||
|
|
||||||
func TestPubKeys(t *testing.T) {
|
func TestPubKeys(t *testing.T) {
|
||||||
for _, test := range pubKeyTests {
|
for _, test := range pubKeyTests {
|
||||||
_, err := btcec.ParsePubKey(test.key, btcec.S256())
|
pk, err := btcec.ParsePubKey(test.key, btcec.S256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if test.isValid {
|
if test.isValid {
|
||||||
t.Errorf("%s pubkey failed when shouldn't %v",
|
t.Errorf("%s pubkey failed when shouldn't %v",
|
||||||
|
@ -206,6 +213,22 @@ func TestPubKeys(t *testing.T) {
|
||||||
if !test.isValid {
|
if !test.isValid {
|
||||||
t.Errorf("%s counted as valid when it should fail",
|
t.Errorf("%s counted as valid when it should fail",
|
||||||
test.name)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,22 @@
|
||||||
github.com/conformal/btcec/signature.go ParseSignature 100.00% (41/41)
|
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.doubleJacobian 100.00% (21/21)
|
||||||
github.com/conformal/btcec/btcec.go KoblitzCurve.ScalarMult 100.00% (9/9)
|
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/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 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.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 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 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/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/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.addJacobian 91.67% (55/60)
|
||||||
github.com/conformal/btcec/btcec.go KoblitzCurve.affineFromJacobian 90.00% (9/10)
|
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/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