github.com/decred/dcrlnd@v0.7.6/aezeed/README.md (about)

     1  # aezeed
     2  
     3  [In this PR](https://github.com/lightningnetwork/lnd/pull/773) we added a new package implementing the aezeed cipher
     4  seed scheme (based on [aez](http://web.cs.ucdavis.edu/~rogaway/aez/)).
     5  
     6  This new scheme aims to address
     7  two major features lacking in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki): versioning, and a
     8  wallet birthday. The lack a version means that wallets may not
     9  necessarily know how to re-derive addresses during the recovery
    10  process. A lack of a birthday means that wallets don’t know how far
    11  back to look in the chain to ensure that they derive all the proper
    12  user addresses. Additionally, BIP39 use a very weak [KDF](https://en.wikipedia.org/wiki/Key_derivation_function). We use
    13  scrypt with modern parameters (n=32768, r=8, p=1). A set of benchmarks has
    14  been added, on my laptop I get about 100ms per attempt):
    15  
    16  ```bash
    17  ⛰ go test -run=XXX -bench=.
    18  
    19  goos: linux
    20  goarch: amd64
    21  pkg: github.com/lightningnetwork/lnd/aezeed
    22  BenchmarkTomnemonic-4                 20          93280730 ns/op        33559670 B/op         36 allocs/op
    23  BenchmarkToCipherSeed-4               10         102323892 ns/op        36915684 B/op         41 allocs/op
    24  PASS
    25  ok      github.com/lightningnetwork/lnd/aezeed  4.168s
    26  ```
    27  
    28  Aside from addressing the shortcomings of BIP 39, an aezeed cipher seed
    29  can both be upgraded, and have its password changed.
    30  
    31  Sample seed:
    32  
    33  ```text
    34  ability dance scatter raw fly dentist bar nominee exhaust wine snap super cost case coconut ticket spread funny grain chimney aspect business quiz ginger
    35  ```
    36  
    37  ## Plaintext aezeed encoding
    38  
    39  The aezeed scheme addresses these two drawbacks and adds a number of
    40  desirable features. First, we start with the following plaintext seed:
    41  
    42  ```text
    43  1 byte internal version || 2 byte timestamp || 16 bytes of entropy
    44  ```
    45  
    46  The version field is for wallets to be able to know how to re-derive
    47  the keys of the wallet.
    48  
    49  The 2 byte timestamp is expressed in Decred Days Genesis, meaning that
    50  the number of days since the timestamp in Decred’s genesis block. This
    51  allow us to save space, and also avoid using a wasteful level of
    52  granularity. This can currently express time up until 2188.
    53  
    54  Finally, the entropy is raw entropy that should be used to derive the
    55  wallet’s HD root.
    56  
    57  ## aezeed enciphering/deciperhing
    58  
    59  Next, we’ll take the plaintext seed described above and encipher it to
    60  procure a final cipher text. We’ll then take this cipher text (the
    61  _CipherSeed_) and encode that using a 24-word mnemonic. The enciphering
    62  process takes a user-defined passphrase. If no passphrase is provided,
    63  then the string “aezeed” will be used.
    64  
    65  To encipher a plaintext seed (19 bytes) to arrive at an enciphered
    66  cipher seed (33 bytes), we apply the following operations:
    67  
    68  * First we take the external version and append it to our buffer. The
    69  external version describes how we encipher. For the first version
    70  (version 0), we’ll use scrypt(n=32768, r=8, p=1) and aezeed.
    71  * Next, we’ll use scrypt (with the version 9 params) to generate a
    72  strong key for encryption. We’ll generate a 32-byte key using 5 bytes
    73  as a salt. The usage of the salt is meant to make the creation of
    74  rainbow tables infeasible.
    75  * Next, the enciphering process. We use aez, modern AEAD with
    76  nonce-misuse resistance properties. The important trait we exploit is
    77  that it’s an arbitrary input length block cipher. Additionally, it
    78  has what’s essentially a configurable MAC size. In our scheme we’ll use
    79  a value of 8, which acts as a 64-bit checksum. We’ll encrypt with our
    80  generated seed, and use an AD of (version || salt).
    81  * Finally, we’ll encode this 33-byte cipher text using the default
    82  word list of BIP 39 to produce 24 English words.
    83  
    84  ## Properties of the aezeed cipher seed
    85  
    86  The aezeed cipher seed scheme has a few cool properties, notably:
    87  
    88  * The mnemonic itself is a cipher text, meaning leaving it in
    89  plaintext is advisable if the user also sets a passphrase. This is in
    90  contrast to BIP 39 where the mnemonic alone (without a passphrase) may
    91  be sufficient to steal funds.
    92  * A cipherseed can be modified to change the passphrase. This
    93  means that if the users wants a stronger passphrase, they can decipher
    94  (with the old passphrase), then encipher (with a new passphrase).
    95  Compared to BIP 39, where if the users used a passphrase, since the
    96  mapping is one way, they can’t change the passphrase of their existing
    97  HD key chain.
    98  * A cipher seed can be upgraded. Since we have an external version,
    99  offline tools can be provided to decipher using the old params, and
   100  encipher using the new params. In the future if we change ciphers,
   101  change scrypt, or just the parameters of scrypt, then users can easily
   102  upgrade their seed with an offline tool.