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:
parent
bb2568cc53
commit
ddd1d92ff1
183 changed files with 0 additions and 0 deletions
125
_pkg.dev/crypto/privatekey/privatekey.go
Executable file
125
_pkg.dev/crypto/privatekey/privatekey.go
Executable 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
|
||||
}
|
48
_pkg.dev/crypto/privatekey/privatekey_test.go
Executable file
48
_pkg.dev/crypto/privatekey/privatekey_test.go
Executable 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))
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue