Account key creation ideas for Polkadot

Already posted as https://forum.web3.foundation/t/account-key-creation-ideas-for-polkadot/68
This commit is contained in:
Jeff Burdges
2019-01-06 20:42:29 +01:00
parent e12cba6a02
commit a430ffdf1a
2 changed files with 23 additions and 3 deletions
+5 -3
View File
@@ -4,7 +4,7 @@ In this post, we shall first give a high level view of the various signing keys
We have roughly four cryptographic layers in Polkadot:
- *Account keys* are owned by users and tied to one actual dot denominated account on Polkadot. Accounts could be staked/bonded, unstaked/unbonded, or unstaking/unbonding, but only an unstaked/unbonded account key can transfer dots from one account to another.
- *Account keys* are owned by users and tied to one actual dot denominated account on Polkadot. Accounts could be staked/bonded, unstaked/unbonded, or unstaking/unbonding, but only an unstaked/unbonded account key can transfer dots from one account to another.
- *Nominator keys* provide a certificate chain between staked/bonded account keys and the session keys used by nodes in block production or validating. As nominator keys cannot transfer dots, they insulate account keys, which may remain air gapped, from nodes actually running on the internet.
- *Session keys* are actually several keys kept together that provide the various signing functions required by validators, including a couple types of verifiable random function (VRF) keys.
- *Transport layer signing keys* are used by libp2p to authenticate connections between nodes. We shall either certify these with the session key or perhaps include them directly in the session key.
@@ -14,13 +14,15 @@ We have roughly four cryptographic layers in Polkadot:
We believe Polkadot accounts should primarily use Schnorr signatures with both public keys and the `R` point in the signature encoded using the [Ristretto](https://ristretto.group) point compression for the Ed25519 curve. We should collaborate with the [dalek ecosystem](https://github.com/dalek-cryptography) for which Ristretto was developed, but provide a simpler signature crate, for which [schnorr-dalek](https://github.com/w3f/schnorr-dalek) provides a first step.
I'll write a second longer post outlining the reasons for this choice, while providing only a high level summary here:
I'll write a another comment outlining the reasons for this choice, while providing only a high level summary here:
Account keys must support the diverse functionality desired of account keys on other systems like Ethereum and Bitcoin. As such, our account keys shall use Schnorr signatures because these support fast batch verification and hierarchical deterministic key derivation ala [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#Child_key_derivation_CKD_functions). All features from the [Bitcoin Schnoor wishlist](https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki) provides a case for Schnorr signatures matter too, like
- interactive threshold and multi-signaturtes, as well as
- adaptor, and perhaps even blind, signatures for swaps and payment channels.
We make conservative curve choices here because account keys must live for decades. In particular, we avoid pairing-based cryptography and BLS signatures for accounts, at the cost of true aggregation of the signatures in a block when verifying blocks, and less interactive threshold and multi-signaturtes. [1].
In the past, there was a tricky choice between the more secure curves:
@@ -75,7 +77,7 @@ A session public key record has a prefix consisting of the above three keys, alo
## Transport layer - libp2p
There are numerous transports for libp2p, but only QUIC was designed to be secure. Instead, one routes traffic through libp2p's secio protocol. We trust QUIC's cryptographic layer which is TLS 1.3, but secio itself is a home brew jobs by Protocol Labs with no serious security analysis, which usually [goes](https://github.com/tendermint/tendermint/issues/3010) [poorly](https://github.com/tendermint/kms/issues/111).
There are numerous transports for libp2p, but only QUIC was designed to be secure. Instead, one routes traffic through [libp2p's secio protocol](https://github.com/libp2p/specs/pull/106). We trust QUIC's cryptographic layer which is TLS 1.3, but secio itself is a home brew jobs by Protocol Labs with no serious security analysis, which usually [goes](https://github.com/tendermint/tendermint/issues/3010) [poorly](https://github.com/tendermint/kms/issues/111).
There was some minimal discussion of secio's security but [Dominic Tarr](https://github.com/auditdrivencrypto/secure-channel/blob/master/prior-art.md#ipfss-secure-channel) raised some concerns in the [original pull request](https://github.com/ipfs/go-ipfs/pull/34). I'll raise several concerns from that discussion:
+18
View File
@@ -0,0 +1,18 @@
https://forum.web3.foundation/t/account-key-creation-ideas-for-polkadot/68
# Account key creation ideas for Polkadot
We found a trick for using Ed25519 "mini" private keys in [schnorr-dalek](https://github.com/w3f/schnorr-dalek/blob/master/src/keys.rs), meaning users' "mini" private key consists of 32 bytes of unstructured entropy.
There are no serious problems with [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) so we suggest a similar strategy for deriving secret keys in Polkadot. We could however modernize BIP39 in a couple small but straightforward ways:
- *Argon2id should replace PBKDF2.* Adam Langely sugests [using time=2 and 64mb of memopry](https://github.com/golang/crypto/commit/d9133f5469342136e669e85192a26056b587f503) for interactive scenarios like this. In principle, one might question if this scenario should truly be considered interactive, but conversely one could imagine running this on relatively constrained devices. We might also improve the [argone2rs](https://github.com/bryant/argon2rs/issues) crate too, especially to [ensure we use at least v1.3 since v1.2.1 got weaker](https://crypto.stackexchange.com/a/40000).
- *Rejection sampling to support larger wordlists.* We could employ rejection sampling from the initial entropy stream to avoid tying ourselves to the list size being a power of two, as BIP39 seemingly requires. We can provide roughly the existing error correction from BIP32, even working in a ring of this order.
- *Actually provide a larger wordlist.* We're discussing enough entropy that users might benefit form using diceware-like word lists with 12.9 bits of entropy per word, as opposed to BIP32's 11 bits of entropy per word. It's possible some diceware word lists contained confusable words, but reviews exists at least for English. We might worry that larger wordlists might simply not exist for some languges. It's also easier to quickly curate shorter lists.
There are also more speculative directions for possible improvements:
- *Improve error correction.* Right now BIP39 has only a basic checksum for error correction. We could design schemes that corrected errors by choosing the words using Reed-Solomon, meaning non-systematic word list creation with code words, except naively this limits our word list sizes to finite field sizes, meaning prime powers. We would instead likely run Reed-Solomon separately on each prime power divisor of the word list's order. We should however evaluate alternatives like other [generalisations of Reed-Solomon codes to rings](https://hal.inria.fr/hal-00670004/file/article.pdf), or even working in a field of slightly larger order and reject choices that fall outside the wordlist.
- *Support multiple Argon2id configurations.* We might conceivably support multiple argon2id configurations, if small device constraints become a serious concern. We could select among a few argon2id configuration options using yet another output from the Reed-Solomon code. We'd simply use rejection sampling to choose the user's desired configuration.