/
keypair.go
74 lines (62 loc) · 1.92 KB
/
keypair.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2017 The nem-toolchain project authors. All rights reserved.
// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
// Package keypair responses for account's private/public crypto keys.
package keypair
import (
"bytes"
"crypto/rand"
"fmt"
"io"
"github.com/nem-toolchain/nem-toolchain/pkg/core"
"golang.org/x/crypto/ed25519"
"golang.org/x/crypto/ripemd160"
"golang.org/x/crypto/sha3"
)
const (
// PrivateBytes stores the private key length in bytes
PrivateBytes = 32
// PublicBytes stores the public key length in bytes
PublicBytes = 32
)
// KeyPair is a private/public crypto key pair.
type KeyPair struct {
Private []byte
Public []byte
}
// Gen generates a new private/public key pair using entropy from crypto rand.
func Gen() KeyPair {
seed := make([]byte, PrivateBytes)
_, err := io.ReadFull(rand.Reader, seed[:])
if err != nil {
panic("assert: cryptographically strong pseudo-random generator internal error")
}
pair, _ := FromSeed(seed)
return pair
}
// FromSeed generates a new private/public key pair using specified private key
func FromSeed(seed []byte) (KeyPair, error) {
if len(seed) != PrivateBytes {
return KeyPair{},
fmt.Errorf("insufficient seed length, should be %d, but got %d", PrivateBytes, len(seed))
}
pub, pr, err := ed25519.GenerateKey(bytes.NewReader(seed))
if err != nil {
panic("assert: ed25519 GenerateKey function internal error")
}
return KeyPair{pr[:PrivateBytes], pub}, nil
}
// Address converts a key pair into corresponding address string representation.
func (pair KeyPair) Address(chain core.Chain) Address {
h := sha3.SumKeccak256(pair.Public)
r := ripemd160.New()
_, err := r.Write(h[:])
if err != nil {
panic("assert: Ripemd160 hash function internal error")
}
b := append([]byte{chain.Id}, r.Sum(nil)...)
h = sha3.SumKeccak256(b)
a := append(b, h[:4]...)
addr := Address{}
copy(addr[:], a[:])
return addr
}