|
| 1 | +package aptoskey |
| 2 | + |
| 3 | +import ( |
| 4 | + "crypto" |
| 5 | + "crypto/ed25519" |
| 6 | + crypto_rand "crypto/rand" |
| 7 | + "fmt" |
| 8 | + "io" |
| 9 | + |
| 10 | + "golang.org/x/crypto/sha3" |
| 11 | + |
| 12 | + "github.com/smartcontractkit/chainlink-common/keystore/internal" |
| 13 | +) |
| 14 | + |
| 15 | +// Key represents Aptos key |
| 16 | +type Key struct { |
| 17 | + // TODO: store initial Account() derivation to support key rotation |
| 18 | + raw internal.Raw |
| 19 | + signFn func(io.Reader, []byte, crypto.SignerOpts) ([]byte, error) |
| 20 | + pubKey ed25519.PublicKey |
| 21 | +} |
| 22 | + |
| 23 | +func KeyFor(raw internal.Raw) Key { |
| 24 | + privKey := ed25519.NewKeyFromSeed(internal.Bytes(raw)) |
| 25 | + pubKey := privKey.Public().(ed25519.PublicKey) |
| 26 | + return Key{ |
| 27 | + raw: raw, |
| 28 | + signFn: privKey.Sign, |
| 29 | + pubKey: pubKey, |
| 30 | + } |
| 31 | +} |
| 32 | + |
| 33 | +// New creates new Key |
| 34 | +func New() (Key, error) { |
| 35 | + return newFrom(crypto_rand.Reader) |
| 36 | +} |
| 37 | + |
| 38 | +// MustNewInsecure return Key if no error |
| 39 | +func MustNewInsecure(reader io.Reader) Key { |
| 40 | + key, err := newFrom(reader) |
| 41 | + if err != nil { |
| 42 | + panic(err) |
| 43 | + } |
| 44 | + return key |
| 45 | +} |
| 46 | + |
| 47 | +// newFrom creates new Key from a provided random reader |
| 48 | +func newFrom(reader io.Reader) (Key, error) { |
| 49 | + pub, priv, err := ed25519.GenerateKey(reader) |
| 50 | + if err != nil { |
| 51 | + return Key{}, err |
| 52 | + } |
| 53 | + return Key{ |
| 54 | + raw: internal.NewRaw(priv.Seed()), |
| 55 | + signFn: priv.Sign, |
| 56 | + pubKey: pub, |
| 57 | + }, nil |
| 58 | +} |
| 59 | + |
| 60 | +// ID gets Key ID |
| 61 | +func (key Key) ID() string { |
| 62 | + return key.PublicKeyStr() |
| 63 | +} |
| 64 | + |
| 65 | +// https://github.com/aptos-foundation/AIPs/blob/main/aips/aip-40.md#long |
| 66 | +func (key Key) Account() string { |
| 67 | + authKey := sha3.Sum256(append([]byte(key.pubKey), 0x00)) |
| 68 | + return fmt.Sprintf("%064x", authKey) |
| 69 | +} |
| 70 | + |
| 71 | +// GetPublic get Key's public key |
| 72 | +func (key Key) GetPublic() ed25519.PublicKey { |
| 73 | + return key.pubKey |
| 74 | +} |
| 75 | + |
| 76 | +// PublicKeyStr returns hex encoded public key |
| 77 | +func (key Key) PublicKeyStr() string { |
| 78 | + return fmt.Sprintf("%064x", key.pubKey) |
| 79 | +} |
| 80 | + |
| 81 | +// Raw returns the seed from private key |
| 82 | +func (key Key) Raw() internal.Raw { return key.raw } |
| 83 | + |
| 84 | +// Sign is used to sign a message |
| 85 | +func (key Key) Sign(msg []byte) ([]byte, error) { |
| 86 | + return key.signFn(crypto_rand.Reader, msg, crypto.Hash(0)) // no specific hash function used |
| 87 | +} |
0 commit comments