forked from TrueCloudLab/neoneo-go
Merge pull request #1046 from nspcc-dev/fix-key-recovery-interops
Fix key recovery interops
This commit is contained in:
commit
4732103294
4 changed files with 51 additions and 19 deletions
|
@ -626,7 +626,7 @@ func (ic *interopContext) eccRecover(curve elliptic.Curve, v *vm.VM) error {
|
|||
v.Estack().PushVal([]byte{})
|
||||
return nil
|
||||
}
|
||||
v.Estack().PushVal(pKey.Bytes()[1:])
|
||||
v.Estack().PushVal(pKey.UncompressedBytes()[1:])
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ func TestSecp256k1Recover(t *testing.T) {
|
|||
X: privateKey.PubKey().X,
|
||||
Y: privateKey.PubKey().Y,
|
||||
}
|
||||
expected := pubKey.Bytes()[1:]
|
||||
expected := pubKey.UncompressedBytes()[1:]
|
||||
|
||||
// We don't know which of two recovered keys suites, so let's try both.
|
||||
putOnStackGetResult := func(isEven bool) []byte {
|
||||
|
@ -505,7 +505,7 @@ func TestSecp256r1Recover(t *testing.T) {
|
|||
messageHash := hash.Sha256(message).BytesBE()
|
||||
signature := privateKey.Sign(message)
|
||||
require.True(t, privateKey.PublicKey().Verify(signature, messageHash))
|
||||
expected := privateKey.PublicKey().Bytes()[1:]
|
||||
expected := privateKey.PublicKey().UncompressedBytes()[1:]
|
||||
|
||||
// We don't know which of two recovered keys suites, so let's try both.
|
||||
putOnStackGetResult := func(isEven bool) []byte {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package keys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/x509"
|
||||
|
@ -19,6 +18,9 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// coordLen is the number of bytes in serialized X or Y coordinate.
|
||||
const coordLen = 32
|
||||
|
||||
// PublicKeys is a list of public keys.
|
||||
type PublicKeys []*PublicKey
|
||||
|
||||
|
@ -95,23 +97,49 @@ func NewPublicKeyFromString(s string) (*PublicKey, error) {
|
|||
return pubKey, nil
|
||||
}
|
||||
|
||||
// Bytes returns the byte array representation of the public key.
|
||||
func (p *PublicKey) Bytes() []byte {
|
||||
// getBytes serializes X and Y using compressed or uncompressed format.
|
||||
func (p *PublicKey) getBytes(compressed bool) []byte {
|
||||
if p.IsInfinity() {
|
||||
return []byte{0x00}
|
||||
}
|
||||
|
||||
var (
|
||||
x = p.X.Bytes()
|
||||
paddedX = append(bytes.Repeat([]byte{0x00}, 32-len(x)), x...)
|
||||
prefix = byte(0x03)
|
||||
)
|
||||
|
||||
if p.Y.Bit(0) == 0 {
|
||||
prefix = byte(0x02)
|
||||
var resLen = 1 + coordLen
|
||||
if !compressed {
|
||||
resLen += coordLen
|
||||
}
|
||||
var res = make([]byte, resLen)
|
||||
var prefix byte
|
||||
|
||||
return append([]byte{prefix}, paddedX...)
|
||||
xBytes := p.X.Bytes()
|
||||
copy(res[1+coordLen-len(xBytes):], xBytes)
|
||||
if compressed {
|
||||
if p.Y.Bit(0) == 0 {
|
||||
prefix = 0x02
|
||||
} else {
|
||||
prefix = 0x03
|
||||
}
|
||||
} else {
|
||||
prefix = 0x04
|
||||
yBytes := p.Y.Bytes()
|
||||
copy(res[1+coordLen+coordLen-len(yBytes):], yBytes)
|
||||
|
||||
}
|
||||
res[0] = prefix
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// Bytes returns byte array representation of the public key in compressed
|
||||
// form (33 bytes with 0x02 or 0x03 prefix, except infinity which is always 0).
|
||||
func (p *PublicKey) Bytes() []byte {
|
||||
return p.getBytes(true)
|
||||
}
|
||||
|
||||
// UncompressedBytes returns byte array representation of the public key in
|
||||
// uncompressed form (65 bytes with 0x04 prefix, except infinity which is
|
||||
// always 0).
|
||||
func (p *PublicKey) UncompressedBytes() []byte {
|
||||
return p.getBytes(false)
|
||||
}
|
||||
|
||||
// NewPublicKeyFromASN1 returns a NEO PublicKey from the ASN.1 serialized key.
|
||||
|
|
|
@ -89,10 +89,14 @@ func TestPubkeyToAddress(t *testing.T) {
|
|||
|
||||
func TestDecodeBytes(t *testing.T) {
|
||||
pubKey := getPubKey(t)
|
||||
decodedPubKey := &PublicKey{}
|
||||
err := decodedPubKey.DecodeBytes(pubKey.Bytes())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pubKey, decodedPubKey)
|
||||
var testBytesFunction = func(t *testing.T, bytesFunction func() []byte) {
|
||||
decodedPubKey := &PublicKey{}
|
||||
err := decodedPubKey.DecodeBytes(bytesFunction())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, pubKey, decodedPubKey)
|
||||
}
|
||||
t.Run("compressed", func(t *testing.T) { testBytesFunction(t, pubKey.Bytes) })
|
||||
t.Run("uncompressed", func(t *testing.T) { testBytesFunction(t, pubKey.UncompressedBytes) })
|
||||
}
|
||||
|
||||
func TestDecodeBytesBadInfinity(t *testing.T) {
|
||||
|
|
Loading…
Reference in a new issue