pkg: hide it by moving to _pkg.dev

The idea here is to preserve the history of `dev` branch development and its
code when merging with the `master`. Later this code could be moved into the
masters code where appropriate.
This commit is contained in:
Roman Khimov 2019-08-20 18:39:50 +03:00
parent bb2568cc53
commit ddd1d92ff1
183 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,125 @@
package privatekey
import (
"bytes"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"io"
"math/big"
"github.com/CityOfZion/neo-go/pkg/crypto/publickey"
"github.com/CityOfZion/neo-go/pkg/crypto/base58"
"github.com/CityOfZion/neo-go/pkg/crypto/elliptic"
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
"github.com/CityOfZion/neo-go/pkg/crypto/rfc6979"
)
// PrivateKey represents a NEO private key.
type PrivateKey struct {
b []byte
}
// NewPrivateKey will create a new private key
// With curve as Secp256r1
func NewPrivateKey() (*PrivateKey, error) {
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
b := make([]byte, curve.N.BitLen()/8+8)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
return nil, err
}
d := new(big.Int).SetBytes(b)
d.Mod(d, new(big.Int).Sub(curve.N, big.NewInt(1)))
d.Add(d, big.NewInt(1))
p := &PrivateKey{b: d.Bytes()}
return p, nil
}
// NewPrivateKeyFromHex will create a new private key hex string
func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
b, err := hex.DecodeString(str)
if err != nil {
return nil, err
}
return NewPrivateKeyFromBytes(b)
}
// NewPrivateKeyFromBytes returns a NEO PrivateKey from the given byte slice.
func NewPrivateKeyFromBytes(b []byte) (*PrivateKey, error) {
if len(b) != 32 {
return nil, fmt.Errorf(
"invalid byte length: expected %d bytes got %d", 32, len(b),
)
}
return &PrivateKey{b}, nil
}
// PublicKey returns a the public corresponding to the private key
// For the curve secp256r1
func (p *PrivateKey) PublicKey() (*publickey.PublicKey, error) {
var (
c = elliptic.NewEllipticCurve(elliptic.Secp256r1)
q = new(big.Int).SetBytes(p.b)
)
p1, p2 := c.ScalarBaseMult(q.Bytes())
point := elliptic.Point{
X: p1,
Y: p2,
}
if !c.IsOnCurve(p1, p2) {
return nil, errors.New("failed to derive public key using elliptic curve")
}
return &publickey.PublicKey{
Curve: c,
Point: point,
}, nil
}
// WIFEncode will converts a private key
// to the Wallet Import Format for NEO
func WIFEncode(key []byte) (s string) {
if len(key) != 32 {
return "invalid private key length"
}
buf := new(bytes.Buffer)
buf.WriteByte(0x80)
buf.Write(key)
buf.WriteByte(0x01)
checksum, _ := hash.Checksum(buf.Bytes())
buf.Write(checksum)
WIF := base58.Encode(buf.Bytes())
return WIF
}
// Sign will sign the corresponding data using the private key
func (p *PrivateKey) Sign(data []byte) ([]byte, error) {
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
key := p.b
digest, _ := hash.Sha256(data)
r, s, err := rfc6979.SignECDSA(curve, key, digest[:], sha256.New)
if err != nil {
return nil, err
}
curveOrderByteSize := curve.P.BitLen() / 8
rBytes, sBytes := r.Bytes(), s.Bytes()
signature := make([]byte, curveOrderByteSize*2)
copy(signature[curveOrderByteSize-len(rBytes):], rBytes)
copy(signature[curveOrderByteSize*2-len(sBytes):], sBytes)
return signature, nil
}

View file

@ -0,0 +1,48 @@
package privatekey
import (
"encoding/hex"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPrivateKeyToPublicKey(t *testing.T) {
input := "495d528227c7dcc234c690af1222e67cde916dac1652cad97e0263825a8268a6"
privateKey, err := NewPrivateKeyFromHex(input)
if err != nil {
t.Fatal(err)
}
pubKey, _ := privateKey.PublicKey()
pubKeyBytes := pubKey.Bytes()
actual := hex.EncodeToString(pubKeyBytes)
expected := "03cd4c4ee9c8e1fae9d12ecf7c96cb3a057b550393f9e82182c4dae1139871682e"
assert.Equal(t, expected, actual)
}
func TestWIFEncode(t *testing.T) {
input := "29bbf53185a973d2e3803cb92908fd08117486d1f2e7bab73ed0d00255511637"
inputBytes, _ := hex.DecodeString(input)
actual := WIFEncode(inputBytes)
expected := "KxcqV28rGDcpVR3fYg7R9vricLpyZ8oZhopyFLAWuRv7Y8TE9WhW"
assert.Equal(t, expected, actual)
}
func TestSigning(t *testing.T) {
// These were taken from the rfcPage:https://tools.ietf.org/html/rfc6979#page-33
// public key: U = xG
//Ux = 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6
//Uy = 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299
PrivateKey, _ := NewPrivateKeyFromHex("C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721")
data, err := PrivateKey.Sign([]byte("sample"))
if err != nil {
t.Fatal(err)
}
r := "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716"
s := "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8"
assert.Equal(t, strings.ToLower(r+s), hex.EncodeToString(data))
}