aezeed: add README with the text of the PR
This commit is contained in:
parent
0c7451c97c
commit
16ad6aed09
103
aezeed/README.md
Normal file
103
aezeed/README.md
Normal file
@ -0,0 +1,103 @@
|
||||
# aezeed
|
||||
|
||||
[https://github.com/lightningnetwork/lnd/pull/773](In this PR),
|
||||
we add a new package implementing the aezeed cipher
|
||||
seed scheme (based on [http://web.cs.ucdavis.edu/~rogaway/aez/](aez) ).
|
||||
|
||||
This is a new scheme developed that aims to overcome the
|
||||
two major short comings of BIP39: a lack of a version, and a lack of a
|
||||
wallet birthday. A lack a version means that wallets may not
|
||||
necessarily know how to re-derive addresses during the recovery
|
||||
process. A lack of a birthday means that wallets don’t know how far
|
||||
back to look in the chain to ensure that they derive all the proper
|
||||
user addresses. Additionally, BIP39 use a very weak KDF. We use
|
||||
scrypt with modern parameters (n=32768, r=8, p=1). A set of benchmarks has
|
||||
been added, on my laptop I get about 100ms per attempt):
|
||||
|
||||
```bash
|
||||
⛰ go test -run=XXX -bench=.
|
||||
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
pkg: github.com/lightningnetwork/lnd/aezeed
|
||||
BenchmarkTomnemonic-4 20 93280730 ns/op 33559670 B/op 36 allocs/op
|
||||
BenchmarkToCipherSeed-4 10 102323892 ns/op 36915684 B/op 41 allocs/op
|
||||
PASS
|
||||
ok github.com/lightningnetwork/lnd/aezeed 4.168s
|
||||
```
|
||||
|
||||
Aside from addressing the shortcomings of BIP 39 a cipher seed
|
||||
can: be upgraded, and have it's password changed,
|
||||
|
||||
Sample seed:
|
||||
|
||||
```text
|
||||
ability dance scatter raw fly dentist bar nominee exhaust wine snap super cost case coconut ticket spread funny grain chimney aspect business quiz ginger
|
||||
```
|
||||
|
||||
## Plaintext aezeed encoding
|
||||
|
||||
The aezeed scheme addresses these two drawbacks and adds a number of
|
||||
desirable features. First, we start with the following plaintext seed:
|
||||
|
||||
```text
|
||||
1 byte internal version || 2 byte timestamp || 16 bytes of entropy
|
||||
```
|
||||
|
||||
The version field is for wallets to be able to know how to re-derive
|
||||
the keys of the wallet.
|
||||
|
||||
The 2 byte timestamp is expressed in Bitcoin Days Genesis, meaning that
|
||||
the number of days since the timestamp in Bitcoin’s genesis block. This
|
||||
allow us to save space, and also avoid using a wasteful level of
|
||||
granularity. With the currently, this can express time up until 2188.
|
||||
|
||||
Finally, the entropy is raw entropy that should be used to derive
|
||||
wallet’s HD root.
|
||||
|
||||
## aezeed enciphering/deciperhing
|
||||
|
||||
Next, we’ll take the plaintext seed described above and encipher it to
|
||||
procure a final cipher text. We’ll then take this cipher text (the
|
||||
CipherSeed) and encode that using a 24-word mnemonic. The enciphering
|
||||
process takes a user defined passphrase. If no passphrase is provided,
|
||||
then the string “aezeed” will be used.
|
||||
|
||||
To encipher a plaintext seed (19 bytes) to arrive at an enciphered
|
||||
cipher seed (33 bytes), we apply the following operations:
|
||||
|
||||
* First we take the external version an append it to our buffer. The
|
||||
external version describes how we encipher. For the first version
|
||||
(version 0), we’ll use scrypt(n=32768, r=8, p=1) and aezeed.
|
||||
* Next, we’ll use scrypt (with the version 9 params) to generate a
|
||||
strong key for encryption. We’ll generate a 32-byte key using 5 bytes
|
||||
as a salt. The usage of the salt is meant to make the creation of
|
||||
rainbow tables infeasible.
|
||||
* Next, the enciphering process. We use aez, modern AEAD with
|
||||
nonce-misuse resistance properties. The important trait we exploit is
|
||||
that it’s an arbitrary input length block cipher. Additionally, it
|
||||
has what’s essentially a configurable MAC size. In our scheme we’ll use
|
||||
a value of 8, which acts as a 64-bit checksum. We’ll encrypt with our
|
||||
generated seed, and use an AD of (version || salt).
|
||||
* Finally, we’ll encode this 33-byte cipher text using the default
|
||||
world list of BIP 39 to produce 24 english words.
|
||||
|
||||
## Properties of the aezeed cipher seed
|
||||
|
||||
The aezeed cipher seed scheme has a few cool properties, notably:
|
||||
|
||||
* The mnemonic itself is a cipher text, meaning leaving it in
|
||||
plaintext is advisable if the user also set a passphrase. This is in
|
||||
contrast to BIP 39 where the mnemonic alone (without a passrphase) may
|
||||
be sufficient to steal funds.
|
||||
* A cipherseed can be modified to change the passphrase. This
|
||||
means that if the users wants a stronger passphrase, they can decipher
|
||||
(with the old passphrase), then encipher (with a new passphrase).
|
||||
Compared to BIP 39, where if the users used a passphrase, since the
|
||||
mapping is one way, they can’t change the passphrase of their existing
|
||||
HD key chain.
|
||||
* A cipher seed can be upgraded. Since we have an external version,
|
||||
offline tools can be provided to decipher using the old params, and
|
||||
encipher using the new params. In the future if we change ciphers,
|
||||
change scrypt, or just the parameters of scrypt, then users can easily
|
||||
upgrade their seed with an offline tool.
|
Loading…
Reference in New Issue
Block a user