Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A keychain functionality proposal #2

Open
vladiuz1 opened this issue Mar 20, 2018 · 5 comments
Open

A keychain functionality proposal #2

vladiuz1 opened this issue Mar 20, 2018 · 5 comments
Assignees

Comments

@vladiuz1
Copy link
Contributor

vladiuz1 commented Mar 20, 2018

AIP: -
  Title: Keychain application
  Status: Draft
  Type: Client
  Author: @vladiuz1 (vs@array.io)
  Created: 2018-03-20

Abstract

A keychain is a multiformart multiplatform secure keystore application. At the moment a developer of multichain functionality is using different formats of storing keys. bitcoind, geth keystore, electrum's keyfiles all use the same public/private key standards but store them in different file formats, and have different interfaces to interract with keys.

Motivation

  • Multi-blockchain wallets. Same key - multiple currencies.
  • Keep your crypto in same keystore, and manage with one (or more) client application.
  • Separate client application from keystore for added security.
  • Use the keychain for cold wallets.
  • Unified interface to sign a transaction generated for any crypto currency.

Most blockchain project's wallets have duplicate functionality, and many differ only in the hash function signing transactions and generating addresses. However functionally it is the same public/private key cryptography with repeating functionality. create/sign/get public key.

Array.io client application can eventually be used for design of multi-blockchain applications. For example direct atomic swaps, lightning network applications, multi-blockchain wallets, etc. A keystorage that can keep and sign a key from any blockchain is extremely helpful. Security of keeping the key in a dapps environment is of utmost importance. Hence keychain environment must be separated from client application.

Summary

An Array.io Keychain is an application that creates and manages private/public key pairs and signs transactions. It is a standalone application that can be run in commandline or gui mode.

screenshot-2018-3-21 array io - array-io-keychain-list moqups 1

The most important functionality of the keychain is ability to sign transactions. Most blockchain projects today are using the same public/private key algorithm - secp256k1. And one key may be used for many different blockchains. The keychain must be modular application that knows how to sign trsansactions of multiple blockchains. It must understand multiple raw transaction formats eventually.

Another important command of the keychain is generation key pairs. As part of generation flow, a user must be prompted to write down a 12 word mnemonic seed.

And since the generation of keys is the main feature, we must also allow adding functionality to recognize multiple wallet formats, so keys could be conveniently imported into keychain from other client formats. E.g. electrum, ethereum, bitcoind's wallet.dat, etc...

screen shot 2018-03-21 at 03 19 43

Even though this is a standalone application it will rarely be launched by a user in either GUI or command line mode. It will most often be used by dapps server or array-io-node to sign transaction in a pipeline mode. Where the output of node or server is piped to the input of array-io-keychain.

Specification

Synopsis

arrayio-keychain command [options] [arguments]

List of commands:

Command Arguments Options Result Description Issue
list key list list all master keys in keychain
sign key_file, raw_tx -hd_path, -in_format, -out_format signature sing a raw transaction
public_key key_file -hd_path, -out_format public_key get public key for the wallet #18
create key_file -cruve, -cipher success create a new keypair
seed key_file -language seed view BIP39 mnemonic seed for the key
restore key_file -curve, -cipher, -language success restore key pair from a BIP39 seed
remove key_file -delete success remove a key from keychain
export key_file, filename -format success export key to an alternative format
import filename, key_file -format, -cipher success import key from another format
list-ciphers <list> list available ciphers you can use to encrypt your wallet
list-curves <list> list availble curves
help command display help

Modes of operation

  • command line
  • pipeline
  • websocket

Example usage:

Commandline:

$ array-io-keychain sign —keyname=test0 --chainid=1 --in-format=hex --out-format=hex 871689d060721b5cec5a010080841e00000000000011130065cd1d0000000000000000
< 1f3314428fe189b2a5424b874dc4ef25c8df65c9d13504ede32a2b2c4c8ada5041161705139e81b981c5c31336d719cf40bd5619a24d890c89b1772944c3fffcc4

Pipeline:

$ array-io-keychain —keyname=test0
> sign --chainid=1 --in-format=hex --out-format=hex 871689d060721b5cec5a010080841e00000000000011130065cd1d0000000000000000
< 1f3314428fe189b2a5424b874dc4ef25c8df65c9d13504ede32a2b2c4c8ada5041161705139e81b981c5c31336d719cf40bd5619a24d890c89b1772944c3fffcc4
@vladiuz1
Copy link
Contributor Author

vladiuz1 commented Mar 21, 2018

during our brainstorm sessions it was suggested to make a pipeline interface for signing/locking/unlocking wallet. but i am thinking websocket daemon maybe a better choice, since it allows us to integrate into browsers, and it may become a standard for in-browser use for wallets like mew. and be used well beyond array.io

@vladiuz1
Copy link
Contributor Author

vladiuz1 commented Mar 22, 2018

Useful links:

@tsrman
Copy link

tsrman commented Mar 22, 2018

Bitshares uses a different (not BIP39 compatible) mechanism for generate private keys from seeds:

Keys in Graphene are derived from a seed brain key which is a string of
16 words out of a predefined dictionary with 49744 words. It is a
simple single-chain key derivation scheme that is not compatible with
BIP44 but easy to use.
Given the brain key, a private key is derived as:
  privkey = SHA256(SHA512(brainkey + " " + sequence))
Incrementing the sequence number yields a new key that can be
regenerated given the brain key.

@vladiuz1
Copy link
Contributor Author

vladiuz1 commented Mar 22, 2018

@tsrman we don't really care about that, we can create our own scheme.

https://en.bitcoin.it/wiki/Elliptic_Curve_Digital_Signature_Algorithm (used in bitshares and other crypto):

private key: A secret number, known only to the person that generated it. A private key is essentially a randomly generated number. In Bitcoin, someone with the private key that corresponds to funds on the public ledger can spend the funds. In Bitcoin, a private key is a single unsigned 256 bit integer (32 bytes).

The private key is an ECDSA secp256k1, and is a random number. This secp256k1 has to be a number between 1 and >115792089237316195423570985008687907852837564279074904382605163141518161494336 (or in hexadecimal, between 1 and FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364140).

Derivation scheme from seed to private key is not that important as long as it is deterministic and produces a valid private key. Every blockchain uses own seed->key derivation scheme, its not important, we can use any of them, bitshares for example. Or we can support few different schemes, so we can restore keys from other client applications. It is not so much protocol dependant feature, it is more implementation dependant. Even in bitcoin, different wallets use different scheme. Electrum seed won't work with bitcoind scheme.

privkey = SHA256(SHA512(brainkey + " " + sequence))

It is a nice feature being able to derive few keys from one seed. We can use same scheme if we want. So that when restoring the private key we also offer to provide a sequence number. But in the end, the private key that we restored is still same old secp256k1 private key that we need to keep.

The problem with this scheme is that you can't determine the seed without brain key. So if you restored your private key 1 from your key and saved it in keychain, you can't get the brain key from this key. So, i don't think its a good scheme. Or we need to keep the brainkey itself in the keychain.

@vladiuz1
Copy link
Contributor Author

vladiuz1 commented Mar 22, 2018

Ok
i think we need 1 more operation, called
public_key
and also we need an option to both public_key and sign operations. and this option is:
derive = "m/44'/60'/0'/0"

obviously the public_key operation will show the public key of the key pair,

but the option derive is something interesting, it will give the public key that corresponds to HD wallet or sign with derived private key

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants