mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-22 14:22:37 +01:00
aezeed: fix typos and formatting
This commit is contained in:
parent
4949243d67
commit
83f1c2c9b6
3 changed files with 68 additions and 59 deletions
|
@ -62,7 +62,7 @@ const (
|
|||
// be seen as the size of the equivalent MAC.
|
||||
CipherTextExpansion = 4
|
||||
|
||||
// EntropySize is the number of bytes of entropy we'll use the generate
|
||||
// EntropySize is the number of bytes of entropy we'll use to generate
|
||||
// the seed.
|
||||
EntropySize = 16
|
||||
|
||||
|
@ -78,7 +78,7 @@ const (
|
|||
|
||||
// adSize is the size of the encoded associated data that will be
|
||||
// passed into aez when enciphering and deciphering the seed. The AD
|
||||
// itself (associated data) is just the CipherSeedVersion and salt.
|
||||
// itself (associated data) is just the cipher seed version and salt.
|
||||
adSize = 6
|
||||
|
||||
// checkSumSize is the size of the checksum applied to the final
|
||||
|
@ -93,7 +93,7 @@ const (
|
|||
// We encode our mnemonic using 24 words, so 264 bits (33 bytes).
|
||||
BitsPerWord = 11
|
||||
|
||||
// saltOffset is the index within an enciphered cipherseed that marks
|
||||
// saltOffset is the index within an enciphered cipher seed that marks
|
||||
// the start of the salt.
|
||||
saltOffset = EncipheredCipherSeedSize - checkSumSize - saltSize
|
||||
|
||||
|
@ -103,8 +103,8 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
// Below at the default scrypt parameters that are tied to
|
||||
// CipherSeedVersion zero.
|
||||
// Below at the default scrypt parameters that are tied to cipher seed
|
||||
// version zero.
|
||||
scryptN = 32768
|
||||
scryptR = 8
|
||||
scryptP = 1
|
||||
|
@ -129,7 +129,7 @@ var (
|
|||
)
|
||||
|
||||
// CipherSeed is a fully decoded instance of the aezeed scheme. At a high
|
||||
// level, the encoded cipherseed is the enciphering of: a version byte, a set
|
||||
// level, the encoded cipher seed is the enciphering of: a version byte, a set
|
||||
// of bytes for a timestamp, the entropy which will be used to directly
|
||||
// construct the HD seed, and finally a checksum over the rest. This scheme was
|
||||
// created as the widely used schemes in the space lack two critical traits: a
|
||||
|
@ -151,7 +151,7 @@ var (
|
|||
// users can encrypt the raw "plaintext" seed under distinct passwords to
|
||||
// produce unique mnemonic phrases.
|
||||
type CipherSeed struct {
|
||||
// InternalVersion is the version of the plaintext cipherseed. This is
|
||||
// InternalVersion is the version of the plaintext cipher seed. This is
|
||||
// to be used by wallets to determine if the seed version is compatible
|
||||
// with the derivation schemes they know.
|
||||
InternalVersion uint8
|
||||
|
@ -178,7 +178,7 @@ type CipherSeed struct {
|
|||
func New(internalVersion uint8, entropy *[EntropySize]byte,
|
||||
now time.Time) (*CipherSeed, error) {
|
||||
|
||||
// TODO(roasbeef): pass randomness source? to make fully determinsitc?
|
||||
// TODO(roasbeef): pass randomness source? to make fully deterministic?
|
||||
|
||||
// If a set of entropy wasn't provided, then we'll read a set of bytes
|
||||
// from the CSPRNG of our operating platform.
|
||||
|
@ -272,11 +272,13 @@ func extractAD(encipheredSeed [EncipheredCipherSeedSize]byte) [adSize]byte {
|
|||
return ad
|
||||
}
|
||||
|
||||
// encipher takes a fully populated cipherseed instance, and enciphers the
|
||||
// encipher takes a fully populated cipher seed instance, and enciphers the
|
||||
// encoded seed, then appends a randomly generated seed used to stretch the
|
||||
// passphrase out into an appropriate key, then computes a checksum over the
|
||||
// preceding.
|
||||
func (c *CipherSeed) encipher(pass []byte) ([EncipheredCipherSeedSize]byte, error) {
|
||||
func (c *CipherSeed) encipher(pass []byte) ([EncipheredCipherSeedSize]byte,
|
||||
error) {
|
||||
|
||||
var cipherSeedBytes [EncipheredCipherSeedSize]byte
|
||||
|
||||
// If the passphrase wasn't provided, then we'll use the string
|
||||
|
@ -295,7 +297,7 @@ func (c *CipherSeed) encipher(pass []byte) ([EncipheredCipherSeedSize]byte, erro
|
|||
return cipherSeedBytes, err
|
||||
}
|
||||
|
||||
// Next, we'll encode the serialized plaintext cipherseed into a buffer
|
||||
// Next, we'll encode the serialized plaintext cipher seed into a buffer
|
||||
// that we'll use for encryption.
|
||||
var seedBytes bytes.Buffer
|
||||
if err := c.encode(&seedBytes); err != nil {
|
||||
|
@ -335,7 +337,9 @@ func (c *CipherSeed) encipher(pass []byte) ([EncipheredCipherSeedSize]byte, erro
|
|||
|
||||
// cipherTextToMnemonic converts the aez ciphertext appended with the salt to a
|
||||
// 24-word mnemonic pass phrase.
|
||||
func cipherTextToMnemonic(cipherText [EncipheredCipherSeedSize]byte) (Mnemonic, error) {
|
||||
func cipherTextToMnemonic(cipherText [EncipheredCipherSeedSize]byte) (Mnemonic,
|
||||
error) {
|
||||
|
||||
var words [NumMnemonicWords]string
|
||||
|
||||
// First, we'll convert the ciphertext itself into a bitstream for easy
|
||||
|
@ -356,7 +360,7 @@ func cipherTextToMnemonic(cipherText [EncipheredCipherSeedSize]byte) (Mnemonic,
|
|||
return words, nil
|
||||
}
|
||||
|
||||
// ToMnemonic maps the final enciphered cipher seed to a human readable 24-word
|
||||
// ToMnemonic maps the final enciphered cipher seed to a human-readable 24-word
|
||||
// mnemonic phrase. The password is optional, as if it isn't specified aezeed
|
||||
// will be used in its place.
|
||||
func (c *CipherSeed) ToMnemonic(pass []byte) (Mnemonic, error) {
|
||||
|
@ -374,7 +378,9 @@ func (c *CipherSeed) ToMnemonic(pass []byte) (Mnemonic, error) {
|
|||
|
||||
// Encipher maps the cipher seed to an aez ciphertext using an optional
|
||||
// passphrase.
|
||||
func (c *CipherSeed) Encipher(pass []byte) ([EncipheredCipherSeedSize]byte, error) {
|
||||
func (c *CipherSeed) Encipher(pass []byte) ([EncipheredCipherSeedSize]byte,
|
||||
error) {
|
||||
|
||||
return c.encipher(pass)
|
||||
}
|
||||
|
||||
|
@ -385,7 +391,7 @@ func (c *CipherSeed) BirthdayTime() time.Time {
|
|||
return BitcoinGenesisDate.Add(offset)
|
||||
}
|
||||
|
||||
// Mnemonic is a 24-word passphrase as of CipherSeedVersion zero. This
|
||||
// Mnemonic is a 24-word passphrase as of cipher seed version zero. This
|
||||
// passphrase encodes an encrypted seed triple (version, birthday, entropy).
|
||||
// Additionally, we also encode the salt used with scrypt to derive the key
|
||||
// that the cipher text is encrypted with, and the version which tells us how
|
||||
|
@ -465,7 +471,9 @@ func decipherCipherSeed(cipherSeedBytes [EncipheredCipherSeedSize]byte,
|
|||
|
||||
// Before we perform any crypto operations, we'll re-create and verify
|
||||
// the checksum to ensure that the user input the proper set of words.
|
||||
freshChecksum := crc32.Checksum(cipherSeedBytes[:checkSumOffset], crcTable)
|
||||
freshChecksum := crc32.Checksum(
|
||||
cipherSeedBytes[:checkSumOffset], crcTable,
|
||||
)
|
||||
if freshChecksum != binary.BigEndian.Uint32(checksum) {
|
||||
return plainSeed, ErrIncorrectMnemonic
|
||||
}
|
||||
|
@ -499,7 +507,8 @@ func decipherCipherSeed(cipherSeedBytes [EncipheredCipherSeedSize]byte,
|
|||
// Decipher attempts to decipher the encoded mnemonic by first mapping to the
|
||||
// original ciphertext, then applying our deciphering scheme. ErrInvalidPass
|
||||
// will be returned if the passphrase is incorrect.
|
||||
func (m *Mnemonic) Decipher(pass []byte) ([DecipheredCipherSeedSize]byte, error) {
|
||||
func (m *Mnemonic) Decipher(pass []byte) ([DecipheredCipherSeedSize]byte,
|
||||
error) {
|
||||
|
||||
// Before we attempt to map the mnemonic back to the original
|
||||
// ciphertext, we'll ensure that all the word are actually a part of
|
||||
|
@ -512,7 +521,7 @@ func (m *Mnemonic) Decipher(pass []byte) ([DecipheredCipherSeedSize]byte, error)
|
|||
for i, word := range m {
|
||||
if _, ok := wordDict[word]; !ok {
|
||||
emptySeed := [DecipheredCipherSeedSize]byte{}
|
||||
return emptySeed, ErrUnknownMnenomicWord{
|
||||
return emptySeed, ErrUnknownMnemonicWord{
|
||||
Word: word,
|
||||
Index: uint8(i),
|
||||
}
|
||||
|
@ -537,20 +546,20 @@ func (m *Mnemonic) Decipher(pass []byte) ([DecipheredCipherSeedSize]byte, error)
|
|||
}
|
||||
|
||||
// ChangePass takes an existing mnemonic, and passphrase for said mnemonic and
|
||||
// re-enciphers the plaintext cipher seed into a brand new mnemonic. This can
|
||||
// re-enciphers the plaintext cipher seed into a brand-new mnemonic. This can
|
||||
// be used to allow users to re-encrypt the same seed with multiple pass
|
||||
// phrases, or just change the passphrase on an existing seed.
|
||||
func (m *Mnemonic) ChangePass(oldPass, newPass []byte) (Mnemonic, error) {
|
||||
var newmnemonic Mnemonic
|
||||
var newMnemonic Mnemonic
|
||||
|
||||
// First, we'll try to decrypt the current mnemonic using the existing
|
||||
// passphrase. If this fails, then we can't proceed any further.
|
||||
cipherSeed, err := m.ToCipherSeed(oldPass)
|
||||
if err != nil {
|
||||
return newmnemonic, err
|
||||
return newMnemonic, err
|
||||
}
|
||||
|
||||
// If the deciperhing was successful, then we'll now re-encipher using
|
||||
// If the deciphering was successful, then we'll now re-encipher using
|
||||
// the new user provided passphrase.
|
||||
return cipherSeed.ToMnemonic(newPass)
|
||||
}
|
||||
|
|
|
@ -84,9 +84,9 @@ func assertCipherSeedEqual(t *testing.T, cipherSeed *CipherSeed,
|
|||
func TestAezeedVersion0TestVectors(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// To minimize the number of tests that need to be run,
|
||||
// go through all test vectors in the same test and also check
|
||||
// the birthday calculation while we're at it.
|
||||
// To minimize the number of tests that need to be run, go through all
|
||||
// test vectors in the same test and also check the birthday calculation
|
||||
// while we're at it.
|
||||
for _, v := range version0TestVectors {
|
||||
// First, we create new cipher seed with the given values
|
||||
// from the test vector.
|
||||
|
@ -95,12 +95,12 @@ func TestAezeedVersion0TestVectors(t *testing.T) {
|
|||
t.Fatalf("unable to create seed: %v", err)
|
||||
}
|
||||
|
||||
// Then we need to set the salt to the pre-defined value, otherwise
|
||||
// we'll end up with randomness in our mnemonics.
|
||||
// Then we need to set the salt to the pre-defined value,
|
||||
// otherwise we'll end up with randomness in our mnemonics.
|
||||
cipherSeed.salt = testSalt
|
||||
|
||||
// Now that the seed has been created, we'll attempt to convert it to a
|
||||
// valid mnemonic.
|
||||
// Now that the seed has been created, we'll attempt to convert
|
||||
// it to a valid mnemonic.
|
||||
mnemonic, err := cipherSeed.ToMnemonic(v.password)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create mnemonic: %v", err)
|
||||
|
@ -189,7 +189,7 @@ func TestManualEntropyGeneration(t *testing.T) {
|
|||
}
|
||||
|
||||
// TestInvalidPassphraseRejection tests if a caller attempts to use the
|
||||
// incorrect passprhase for an enciphered seed, then the proper error is
|
||||
// incorrect passphrase for an enciphered seed, then the proper error is
|
||||
// returned.
|
||||
func TestInvalidPassphraseRejection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -228,7 +228,7 @@ func TestRawEncipherDecipher(t *testing.T) {
|
|||
t.Fatalf("unable to create seed: %v", err)
|
||||
}
|
||||
|
||||
// With the cipherseed obtained, we'll now use the raw encipher method
|
||||
// With the cipher seed obtained, we'll now use the raw encipher method
|
||||
// to obtain our final cipher text.
|
||||
cipherText, err := cipherSeed.Encipher(pass)
|
||||
if err != nil {
|
||||
|
@ -270,7 +270,7 @@ func TestInvalidExternalVersion(t *testing.T) {
|
|||
t.Fatalf("unable to create seed: %v", err)
|
||||
}
|
||||
|
||||
// With the cipherseed obtained, we'll now use the raw encipher method
|
||||
// With the cipher seed obtained, we'll now use the raw encipher method
|
||||
// to obtain our final cipher text.
|
||||
pass := []byte("newpasswhodis")
|
||||
cipherText, err := cipherSeed.Encipher(pass)
|
||||
|
@ -312,16 +312,16 @@ func TestChangePassphrase(t *testing.T) {
|
|||
}
|
||||
|
||||
// Now that have the mnemonic, we'll attempt to re-encipher the
|
||||
// passphrase in order to get a brand new mnemonic.
|
||||
// passphrase in order to get a brand-new mnemonic.
|
||||
newPass := []byte("strongerpassyeh!")
|
||||
newmnemonic, err := mnemonic.ChangePass(pass, newPass)
|
||||
newMnemonic, err := mnemonic.ChangePass(pass, newPass)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to change passphrase: %v", err)
|
||||
}
|
||||
|
||||
// We'll now attempt to decipher the new mnemonic using the new
|
||||
// passphrase to arrive at (what should be) the original cipher seed.
|
||||
newCipherSeed, err := newmnemonic.ToCipherSeed(newPass)
|
||||
newCipherSeed, err := newMnemonic.ToCipherSeed(newPass)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to decipher cipher seed: %v", err)
|
||||
}
|
||||
|
@ -332,7 +332,7 @@ func TestChangePassphrase(t *testing.T) {
|
|||
}
|
||||
|
||||
// TestChangePassphraseWrongPass tests that if we have a valid enciphered
|
||||
// cipherseed, but then try to change the password with the *wrong* password,
|
||||
// cipher seed, but then try to change the password with the *wrong* password,
|
||||
// then we get an error.
|
||||
func TestChangePassphraseWrongPass(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -352,7 +352,7 @@ func TestChangePassphraseWrongPass(t *testing.T) {
|
|||
}
|
||||
|
||||
// Now that have the mnemonic, we'll attempt to re-encipher the
|
||||
// passphrase in order to get a brand new mnemonic. However, we'll be
|
||||
// passphrase in order to get a brand-new mnemonic. However, we'll be
|
||||
// using the *wrong* passphrase. This should result in an
|
||||
// ErrInvalidPass error.
|
||||
wrongPass := []byte("kek")
|
||||
|
@ -397,7 +397,7 @@ func TestMnemonicEncoding(t *testing.T) {
|
|||
}
|
||||
|
||||
// TestEncipherDecipher is a property-based test that ensures that given a
|
||||
// version, entropy, and birthday, then we're able to map that to a cipherseed
|
||||
// version, entropy, and birthday, then we're able to map that to a cipher seed
|
||||
// mnemonic, then back to the original plaintext cipher seed.
|
||||
func TestEncipherDecipher(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
@ -406,7 +406,7 @@ func TestEncipherDecipher(t *testing.T) {
|
|||
// ensure that given a random seed tuple (internal version, entropy,
|
||||
// and birthday) we're able to convert that to a valid cipher seed.
|
||||
// Additionally, we should be able to decipher the final mnemonic, and
|
||||
// recover the original cipherseed.
|
||||
// recover the original cipher seed.
|
||||
mainScenario := func(version uint8, entropy [EntropySize]byte,
|
||||
nowInt int64, pass [20]byte) bool {
|
||||
|
||||
|
@ -458,7 +458,7 @@ func TestEncipherDecipher(t *testing.T) {
|
|||
// arbitrary raw seed.
|
||||
func TestSeedEncodeDecode(t *testing.T) {
|
||||
// mainScenario is the primary driver of our property-based test. We'll
|
||||
// ensure that given a random cipher seed, we can encode it an decode
|
||||
// ensure that given a random cipher seed, we can encode it and decode
|
||||
// it precisely.
|
||||
mainScenario := func(version uint8, nowInt int64,
|
||||
entropy [EntropySize]byte) bool {
|
||||
|
@ -506,10 +506,10 @@ func TestSeedEncodeDecode(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestDecipherUnknownMnenomicWord tests that if we obtain a mnemonic, the
|
||||
// TestDecipherUnknownMnemonicWord tests that if we obtain a mnemonic, then
|
||||
// modify one of the words to not be within the word list, then it's detected
|
||||
// when we attempt to map it back to the original cipher seed.
|
||||
func TestDecipherUnknownMnenomicWord(t *testing.T) {
|
||||
func TestDecipherUnknownMnemonicWord(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// First, we'll create a new cipher seed with "test" ass a password.
|
||||
|
@ -532,15 +532,15 @@ func TestDecipherUnknownMnenomicWord(t *testing.T) {
|
|||
mnemonic[randIndex] = "kek"
|
||||
|
||||
// If we attempt to map back to the original cipher seed now, then we
|
||||
// should get ErrUnknownMnenomicWord.
|
||||
// should get ErrUnknownMnemonicWord.
|
||||
_, err = mnemonic.ToCipherSeed(pass)
|
||||
if err == nil {
|
||||
t.Fatalf("expected ErrUnknownMnenomicWord error")
|
||||
t.Fatalf("expected ErrUnknownMnemonicWord error")
|
||||
}
|
||||
|
||||
wordErr, ok := err.(ErrUnknownMnenomicWord)
|
||||
wordErr, ok := err.(ErrUnknownMnemonicWord)
|
||||
if !ok {
|
||||
t.Fatalf("expected ErrUnknownMnenomicWord instead got %T", err)
|
||||
t.Fatalf("expected ErrUnknownMnemonicWord instead got %T", err)
|
||||
}
|
||||
|
||||
if wordErr.Word != "kek" {
|
||||
|
@ -551,24 +551,24 @@ func TestDecipherUnknownMnenomicWord(t *testing.T) {
|
|||
randIndex, wordErr.Index)
|
||||
}
|
||||
|
||||
// If the mnemonic includes a word that is not in the englishList
|
||||
// it fails, even when it is a substring of a valid word
|
||||
// Example: `heart` is in the list, `hear` is not
|
||||
// If the mnemonic includes a word that is not in the englishList it
|
||||
// fails, even when it is a substring of a valid word Example: `heart`
|
||||
// is in the list, `hear` is not.
|
||||
mnemonic[randIndex] = "hear"
|
||||
|
||||
// If we attempt to map back to the original cipher seed now, then we
|
||||
// should get ErrUnknownMnenomicWord.
|
||||
// should get ErrUnknownMnemonicWord.
|
||||
_, err = mnemonic.ToCipherSeed(pass)
|
||||
if err == nil {
|
||||
t.Fatalf("expected ErrUnknownMnenomicWord error")
|
||||
t.Fatalf("expected ErrUnknownMnemonicWord error")
|
||||
}
|
||||
_, ok = err.(ErrUnknownMnenomicWord)
|
||||
_, ok = err.(ErrUnknownMnemonicWord)
|
||||
if !ok {
|
||||
t.Fatalf("expected ErrUnknownMnenomicWord instead got %T", err)
|
||||
t.Fatalf("expected ErrUnknownMnemonicWord instead got %T", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDecipherIncorrectMnemonic tests that if we obtain a cipherseed, but then
|
||||
// TestDecipherIncorrectMnemonic tests that if we obtain a cipher seed, but then
|
||||
// swap out words, then checksum fails.
|
||||
func TestDecipherIncorrectMnemonic(t *testing.T) {
|
||||
// First, we'll create a new cipher seed with "test" ass a password.
|
||||
|
@ -593,7 +593,7 @@ func TestDecipherIncorrectMnemonic(t *testing.T) {
|
|||
|
||||
// If we attempt to decrypt now, we should get a checksum failure.
|
||||
// If we attempt to map back to the original cipher seed now, then we
|
||||
// should get ErrUnknownMnenomicWord.
|
||||
// should get ErrIncorrectMnemonic.
|
||||
_, err = mnemonic.ToCipherSeed(pass)
|
||||
if err != ErrIncorrectMnemonic {
|
||||
t.Fatalf("expected ErrIncorrectMnemonic error")
|
||||
|
|
|
@ -18,9 +18,9 @@ var (
|
|||
"match")
|
||||
)
|
||||
|
||||
// ErrUnknownMnenomicWord is returned when attempting to decipher and
|
||||
// ErrUnknownMnemonicWord is returned when attempting to decipher and
|
||||
// enciphered mnemonic, but a word encountered isn't a member of our word list.
|
||||
type ErrUnknownMnenomicWord struct {
|
||||
type ErrUnknownMnemonicWord struct {
|
||||
// Word is the unknown word in the mnemonic phrase.
|
||||
Word string
|
||||
|
||||
|
@ -29,8 +29,8 @@ type ErrUnknownMnenomicWord struct {
|
|||
Index uint8
|
||||
}
|
||||
|
||||
// Error returns a human readable string describing the error.
|
||||
func (e ErrUnknownMnenomicWord) Error() string {
|
||||
// Error returns a human-readable string describing the error.
|
||||
func (e ErrUnknownMnemonicWord) Error() string {
|
||||
return fmt.Sprintf("word %v isn't a part of default word list "+
|
||||
"(index=%v)", e.Word, e.Index)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue