keys: allow to create keys on arbitrary curve

This commit is contained in:
Evgenii Stratonikov 2020-12-02 15:52:31 +03:00
parent 5bd8ca9597
commit d5b4553bb3
2 changed files with 31 additions and 3 deletions

View file

@ -10,6 +10,7 @@ import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/btcsuite/btcd/btcec"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/rfc6979" "github.com/nspcc-dev/rfc6979"
) )
@ -20,16 +21,26 @@ type PrivateKey struct {
ecdsa.PrivateKey ecdsa.PrivateKey
} }
// NewPrivateKey creates a new random Secp256k1 private key. // NewPrivateKey creates a new random Secp256r1 private key.
func NewPrivateKey() (*PrivateKey, error) { func NewPrivateKey() (*PrivateKey, error) {
priv, x, y, err := elliptic.GenerateKey(elliptic.P256(), rand.Reader) return newPrivateKeyOnCurve(elliptic.P256())
}
// NewSecp256k1PrivateKey creates a new random Secp256k1 private key.
func NewSecp256k1PrivateKey() (*PrivateKey, error) {
return newPrivateKeyOnCurve(btcec.S256())
}
// newPrivateKeyOnCurve creates a new random private key using curve c.
func newPrivateKeyOnCurve(c elliptic.Curve) (*PrivateKey, error) {
priv, x, y, err := elliptic.GenerateKey(c, rand.Reader)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &PrivateKey{ return &PrivateKey{
ecdsa.PrivateKey{ ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{ PublicKey: ecdsa.PublicKey{
Curve: elliptic.P256(), Curve: c,
X: x, X: x,
Y: y, Y: y,
}, },

View file

@ -6,7 +6,9 @@ import (
"testing" "testing"
"github.com/nspcc-dev/neo-go/internal/keytestcases" "github.com/nspcc-dev/neo-go/internal/keytestcases"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestPrivateKey(t *testing.T) { func TestPrivateKey(t *testing.T) {
@ -28,6 +30,21 @@ func TestPrivateKey(t *testing.T) {
} }
} }
func TestNewPrivateKeyOnCurve(t *testing.T) {
msg := []byte{1, 2, 3}
h := hash.Sha256(msg).BytesBE()
t.Run("Secp256r1", func(t *testing.T) {
p, err := NewPrivateKey()
require.NoError(t, err)
p.PublicKey().Verify(p.Sign(msg), h)
})
t.Run("Secp256k1", func(t *testing.T) {
p, err := NewSecp256k1PrivateKey()
require.NoError(t, err)
p.PublicKey().Verify(p.Sign(msg), h)
})
}
func TestPrivateKeyFromWIF(t *testing.T) { func TestPrivateKeyFromWIF(t *testing.T) {
for _, testCase := range keytestcases.Arr { for _, testCase := range keytestcases.Arr {
key, err := NewPrivateKeyFromWIF(testCase.Wif) key, err := NewPrivateKeyFromWIF(testCase.Wif)