aezeed: re-format test cases, use require

This commit is contained in:
Oliver Gugger
2022-05-12 12:47:09 +02:00
parent a02112464a
commit f67776375f

View File

@@ -6,6 +6,8 @@ import (
"testing" "testing"
"testing/quick" "testing/quick"
"time" "time"
"github.com/stretchr/testify/require"
) )
// TestVector defines the values that are used to create a fully initialized // TestVector defines the values that are used to create a fully initialized
@@ -30,53 +32,44 @@ var (
testSalt = [saltSize]byte{ testSalt = [saltSize]byte{
0x73, 0x61, 0x6c, 0x74, 0x31, // equal to "salt1" 0x73, 0x61, 0x6c, 0x74, 0x31, // equal to "salt1"
} }
version0TestVectors = []TestVector{ version0TestVectors = []TestVector{{
{ version: 0,
version: 0, time: BitcoinGenesisDate,
time: BitcoinGenesisDate, entropy: testEntropy,
entropy: testEntropy, salt: testSalt,
salt: testSalt, password: []byte{},
password: []byte{}, expectedMnemonic: [NumMnemonicWords]string{
expectedMnemonic: [NumMnemonicWords]string{ "ability", "liquid", "travel", "stem", "barely", "drastic",
"ability", "liquid", "travel", "stem", "barely", "drastic", "pact", "cupboard", "apple", "thrive", "morning", "oak",
"pact", "cupboard", "apple", "thrive", "morning", "oak", "feature", "tissue", "couch", "old", "math", "inform",
"feature", "tissue", "couch", "old", "math", "inform", "success", "suggest", "drink", "motion", "know", "royal",
"success", "suggest", "drink", "motion", "know", "royal",
},
expectedBirthday: 0,
}, },
{ expectedBirthday: 0,
version: 0, }, {
time: time.Unix(1521799345, 0), // 03/23/2018 @ 10:02am (UTC) version: 0,
entropy: testEntropy, time: time.Unix(1521799345, 0), // 03/23/2018 @ 10:02am (UTC)
salt: testSalt, entropy: testEntropy,
password: []byte("!very_safe_55345_password*"), salt: testSalt,
expectedMnemonic: [NumMnemonicWords]string{ password: []byte("!very_safe_55345_password*"),
"able", "tree", "stool", "crush", "transfer", "cloud", expectedMnemonic: [NumMnemonicWords]string{
"cross", "three", "profit", "outside", "hen", "citizen", "able", "tree", "stool", "crush", "transfer", "cloud",
"plate", "ride", "require", "leg", "siren", "drum", "cross", "three", "profit", "outside", "hen", "citizen",
"success", "suggest", "drink", "require", "fiscal", "upgrade", "plate", "ride", "require", "leg", "siren", "drum",
}, "success", "suggest", "drink", "require", "fiscal", "upgrade",
expectedBirthday: 3365,
}, },
} expectedBirthday: 3365,
}}
) )
func assertCipherSeedEqual(t *testing.T, cipherSeed *CipherSeed, func assertCipherSeedEqual(t *testing.T, cipherSeed *CipherSeed,
cipherSeed2 *CipherSeed) { cipherSeed2 *CipherSeed) {
if cipherSeed.InternalVersion != cipherSeed2.InternalVersion { require.Equal(
t.Fatalf("mismatched versions: expected %v, got %v", t, cipherSeed.InternalVersion, cipherSeed2.InternalVersion,
cipherSeed.InternalVersion, cipherSeed2.InternalVersion) "internal version",
} )
if cipherSeed.Birthday != cipherSeed2.Birthday { require.Equal(t, cipherSeed.Birthday, cipherSeed2.Birthday, "birthday")
t.Fatalf("mismatched birthday: expected %v, got %v", require.Equal(t, cipherSeed.Entropy, cipherSeed2.Entropy, "entropy")
cipherSeed.Birthday, cipherSeed2.Birthday)
}
if cipherSeed.Entropy != cipherSeed2.Entropy {
t.Fatalf("mismatched versions: expected %x, got %x",
cipherSeed.Entropy[:], cipherSeed2.Entropy[:])
}
} }
// TestAezeedVersion0TestVectors tests some fixed test vector values against // TestAezeedVersion0TestVectors tests some fixed test vector values against
@@ -91,31 +84,21 @@ func TestAezeedVersion0TestVectors(t *testing.T) {
// First, we create new cipher seed with the given values // First, we create new cipher seed with the given values
// from the test vector. // from the test vector.
cipherSeed, err := New(v.version, &v.entropy, v.time) cipherSeed, err := New(v.version, &v.entropy, v.time)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Then we need to set the salt to the pre-defined value, // Then we need to set the salt to the pre-defined value,
// otherwise we'll end up with randomness in our mnemonics. // otherwise we'll end up with randomness in our mnemonics.
cipherSeed.salt = testSalt cipherSeed.salt = v.salt
// Now that the seed has been created, we'll attempt to convert // Now that the seed has been created, we'll attempt to convert
// it to a valid mnemonic. // it to a valid mnemonic.
mnemonic, err := cipherSeed.ToMnemonic(v.password) mnemonic, err := cipherSeed.ToMnemonic(v.password)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Finally we compare the generated mnemonic and birthday to the // Finally we compare the generated mnemonic and birthday to the
// expected value. // expected value.
if mnemonic != v.expectedMnemonic { require.Equal(t, v.expectedMnemonic[:], mnemonic[:])
t.Fatalf("mismatched mnemonic: expected %s, got %s", require.Equal(t, v.expectedBirthday, cipherSeed.Birthday)
v.expectedMnemonic, mnemonic)
}
if cipherSeed.Birthday != v.expectedBirthday {
t.Fatalf("mismatched birthday: expected %v, got %v",
v.expectedBirthday, cipherSeed.Birthday)
}
} }
} }
@@ -131,23 +114,17 @@ func TestEmptyPassphraseDerivation(t *testing.T) {
// We'll now create a new cipher seed with an internal version of zero // We'll now create a new cipher seed with an internal version of zero
// to simulate a wallet that just adopted the scheme. // to simulate a wallet that just adopted the scheme.
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that the seed has been created, we'll attempt to convert it to a // Now that the seed has been created, we'll attempt to convert it to a
// valid mnemonic. // valid mnemonic.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Next, we'll try to decrypt the mnemonic with the passphrase that we // Next, we'll try to decrypt the mnemonic with the passphrase that we
// used. // used.
cipherSeed2, err := mnemonic.ToCipherSeed(pass) cipherSeed2, err := mnemonic.ToCipherSeed(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to decrypt mnemonic: %v", err)
}
// Finally, we'll ensure that the uncovered cipher seed matches // Finally, we'll ensure that the uncovered cipher seed matches
// precisely. // precisely.
@@ -165,23 +142,17 @@ func TestManualEntropyGeneration(t *testing.T) {
// We'll now create a new cipher seed with an internal version of zero // We'll now create a new cipher seed with an internal version of zero
// to simulate a wallet that just adopted the scheme. // to simulate a wallet that just adopted the scheme.
cipherSeed, err := New(0, nil, time.Now()) cipherSeed, err := New(0, nil, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that the seed has been created, we'll attempt to convert it to a // Now that the seed has been created, we'll attempt to convert it to a
// valid mnemonic. // valid mnemonic.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Next, we'll try to decrypt the mnemonic with the passphrase that we // Next, we'll try to decrypt the mnemonic with the passphrase that we
// used. // used.
cipherSeed2, err := mnemonic.ToCipherSeed(pass) cipherSeed2, err := mnemonic.ToCipherSeed(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to decrypt mnemonic: %v", err)
}
// Finally, we'll ensure that the uncovered cipher seed matches // Finally, we'll ensure that the uncovered cipher seed matches
// precisely. // precisely.
@@ -197,23 +168,18 @@ func TestInvalidPassphraseRejection(t *testing.T) {
// First, we'll generate a new cipher seed with a test passphrase. // First, we'll generate a new cipher seed with a test passphrase.
pass := []byte("test") pass := []byte("test")
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that we have our cipher seed, we'll encipher it and request a // Now that we have our cipher seed, we'll encipher it and request a
// mnemonic that we can use to recover later. // mnemonic that we can use to recover later.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// If we try to decipher with the wrong passphrase, we should get the // If we try to decipher with the wrong passphrase, we should get the
// proper error. // proper error.
wrongPass := []byte("kek") wrongPass := []byte("kek")
if _, err := mnemonic.ToCipherSeed(wrongPass); err != ErrInvalidPass { _, err = mnemonic.ToCipherSeed(wrongPass)
t.Fatalf("expected ErrInvalidPass, instead got %v", err) require.Equal(t, ErrInvalidPass, err)
}
} }
// TestRawEncipherDecipher tests that callers are able to use the raw methods // TestRawEncipherDecipher tests that callers are able to use the raw methods
@@ -224,36 +190,26 @@ func TestRawEncipherDecipher(t *testing.T) {
// First, we'll generate a new cipher seed with a test passphrase. // First, we'll generate a new cipher seed with a test passphrase.
pass := []byte("test") pass := []byte("test")
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// With the cipher seed 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. // to obtain our final cipher text.
cipherText, err := cipherSeed.Encipher(pass) cipherText, err := cipherSeed.Encipher(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to encipher seed: %v", err)
}
mnemonic, err := cipherTextToMnemonic(cipherText) mnemonic, err := cipherTextToMnemonic(cipherText)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Now that we have the ciphertext (mapped to the mnemonic), we'll // Now that we have the ciphertext (mapped to the mnemonic), we'll
// attempt to decipher it raw using the user's passphrase. // attempt to decipher it raw using the user's passphrase.
plainSeedBytes, err := mnemonic.Decipher(pass) plainSeedBytes, err := mnemonic.Decipher(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to decipher: %v", err)
}
// If we deserialize the plaintext seed bytes, it should exactly match // If we deserialize the plaintext seed bytes, it should exactly match
// the original cipher seed. // the original cipher seed.
var newSeed CipherSeed var newSeed CipherSeed
err = newSeed.decode(bytes.NewReader(plainSeedBytes[:])) err = newSeed.decode(bytes.NewReader(plainSeedBytes[:]))
if err != nil { require.NoError(t, err)
t.Fatalf("unable to decode cipher seed: %v", err)
}
assertCipherSeedEqual(t, cipherSeed, &newSeed) assertCipherSeedEqual(t, cipherSeed, &newSeed)
} }
@@ -266,17 +222,13 @@ func TestInvalidExternalVersion(t *testing.T) {
// First, we'll generate a new cipher seed. // First, we'll generate a new cipher seed.
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// With the cipher seed 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. // to obtain our final cipher text.
pass := []byte("newpasswhodis") pass := []byte("newpasswhodis")
cipherText, err := cipherSeed.Encipher(pass) cipherText, err := cipherSeed.Encipher(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to encipher seed: %v", err)
}
// Now that we have the cipher text, we'll modify the first byte to be // Now that we have the cipher text, we'll modify the first byte to be
// an invalid version. // an invalid version.
@@ -285,10 +237,7 @@ func TestInvalidExternalVersion(t *testing.T) {
// With the version swapped, if we try to decipher it, (no matter the // With the version swapped, if we try to decipher it, (no matter the
// passphrase), it should fail. // passphrase), it should fail.
_, err = decipherCipherSeed(cipherText, []byte("kek")) _, err = decipherCipherSeed(cipherText, []byte("kek"))
if err != ErrIncorrectVersion { require.Equal(t, ErrIncorrectVersion, err)
t.Fatalf("wrong error: expected ErrIncorrectVersion, "+
"got %v", err)
}
} }
// TestChangePassphrase tests that we're able to generate a cipher seed, then // TestChangePassphrase tests that we're able to generate a cipher seed, then
@@ -300,31 +249,23 @@ func TestChangePassphrase(t *testing.T) {
// First, we'll generate a new cipher seed with a test passphrase. // First, we'll generate a new cipher seed with a test passphrase.
pass := []byte("test") pass := []byte("test")
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that we have our cipher seed, we'll encipher it and request a // Now that we have our cipher seed, we'll encipher it and request a
// mnemonic that we can use to recover later. // mnemonic that we can use to recover later.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Now that have the mnemonic, we'll attempt to re-encipher the // 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!") newPass := []byte("strongerpassyeh!")
newMnemonic, err := mnemonic.ChangePass(pass, newPass) newMnemonic, err := mnemonic.ChangePass(pass, newPass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to change passphrase: %v", err)
}
// We'll now attempt to decipher the new mnemonic using the new // We'll now attempt to decipher the new mnemonic using the new
// passphrase to arrive at (what should be) the original cipher seed. // passphrase to arrive at (what should be) the original cipher seed.
newCipherSeed, err := newMnemonic.ToCipherSeed(newPass) newCipherSeed, err := newMnemonic.ToCipherSeed(newPass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to decipher cipher seed: %v", err)
}
// Now that we have the cipher seed, we'll verify that the plaintext // Now that we have the cipher seed, we'll verify that the plaintext
// seed matches *identically*. // seed matches *identically*.
@@ -340,16 +281,12 @@ func TestChangePassphraseWrongPass(t *testing.T) {
// First, we'll generate a new cipher seed with a test passphrase. // First, we'll generate a new cipher seed with a test passphrase.
pass := []byte("test") pass := []byte("test")
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that we have our cipher seed, we'll encipher it and request a // Now that we have our cipher seed, we'll encipher it and request a
// mnemonic that we can use to recover later. // mnemonic that we can use to recover later.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Now that have the mnemonic, we'll attempt to re-encipher the // 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
@@ -358,9 +295,7 @@ func TestChangePassphraseWrongPass(t *testing.T) {
wrongPass := []byte("kek") wrongPass := []byte("kek")
newPass := []byte("strongerpassyeh!") newPass := []byte("strongerpassyeh!")
_, err = mnemonic.ChangePass(wrongPass, newPass) _, err = mnemonic.ChangePass(wrongPass, newPass)
if err != ErrInvalidPass { require.Equal(t, ErrInvalidPass, err)
t.Fatalf("expected ErrInvalidPass, instead got %v", err)
}
} }
// TestMnemonicEncoding uses quickcheck like property based testing to ensure // TestMnemonicEncoding uses quickcheck like property based testing to ensure
@@ -464,9 +399,11 @@ func TestSeedEncodeDecode(t *testing.T) {
entropy [EntropySize]byte) bool { entropy [EntropySize]byte) bool {
now := time.Unix(nowInt, 0) now := time.Unix(nowInt, 0)
day := time.Hour * 24
numDaysSinceGenesis := now.Sub(BitcoinGenesisDate) / day
seed := CipherSeed{ seed := CipherSeed{
InternalVersion: version, InternalVersion: version,
Birthday: uint16(now.Sub(BitcoinGenesisDate) / (time.Hour * 24)), Birthday: uint16(numDaysSinceGenesis),
Entropy: entropy, Entropy: entropy,
} }
@@ -515,16 +452,12 @@ func TestDecipherUnknownMnemonicWord(t *testing.T) {
// First, we'll create a new cipher seed with "test" ass a password. // First, we'll create a new cipher seed with "test" ass a password.
pass := []byte("test") pass := []byte("test")
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that we have our cipher seed, we'll encipher it and request a // Now that we have our cipher seed, we'll encipher it and request a
// mnemonic that we can use to recover later. // mnemonic that we can use to recover later.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// Before we attempt to decrypt the cipher seed, we'll mutate one of // Before we attempt to decrypt the cipher seed, we'll mutate one of
// the word so it isn't actually in our final word list. // the word so it isn't actually in our final word list.
@@ -534,22 +467,10 @@ func TestDecipherUnknownMnemonicWord(t *testing.T) {
// If we attempt to map back to the original cipher seed now, then we // If we attempt to map back to the original cipher seed now, then we
// should get ErrUnknownMnemonicWord. // should get ErrUnknownMnemonicWord.
_, err = mnemonic.ToCipherSeed(pass) _, err = mnemonic.ToCipherSeed(pass)
if err == nil { wordErr := &ErrUnknownMnemonicWord{}
t.Fatalf("expected ErrUnknownMnemonicWord error") require.ErrorAs(t, err, wordErr)
} require.Equal(t, "kek", wordErr.Word)
require.Equal(t, uint8(randIndex), wordErr.Index)
wordErr, ok := err.(ErrUnknownMnemonicWord)
if !ok {
t.Fatalf("expected ErrUnknownMnemonicWord instead got %T", err)
}
if wordErr.Word != "kek" {
t.Fatalf("word mismatch: expected %v, got %v", "kek", wordErr.Word)
}
if int32(wordErr.Index) != randIndex {
t.Fatalf("wrong index detected: expected %v, got %v",
randIndex, wordErr.Index)
}
// If the mnemonic includes a word that is not in the englishList it // 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` // fails, even when it is a substring of a valid word Example: `heart`
@@ -559,13 +480,7 @@ func TestDecipherUnknownMnemonicWord(t *testing.T) {
// If we attempt to map back to the original cipher seed now, then we // If we attempt to map back to the original cipher seed now, then we
// should get ErrUnknownMnemonicWord. // should get ErrUnknownMnemonicWord.
_, err = mnemonic.ToCipherSeed(pass) _, err = mnemonic.ToCipherSeed(pass)
if err == nil { require.ErrorAs(t, err, wordErr)
t.Fatalf("expected ErrUnknownMnemonicWord error")
}
_, ok = err.(ErrUnknownMnemonicWord)
if !ok {
t.Fatalf("expected ErrUnknownMnemonicWord instead got %T", err)
}
} }
// TestDecipherIncorrectMnemonic tests that if we obtain a cipher seed, but then // TestDecipherIncorrectMnemonic tests that if we obtain a cipher seed, but then
@@ -574,16 +489,12 @@ func TestDecipherIncorrectMnemonic(t *testing.T) {
// First, we'll create a new cipher seed with "test" ass a password. // First, we'll create a new cipher seed with "test" ass a password.
pass := []byte("test") pass := []byte("test")
cipherSeed, err := New(0, &testEntropy, time.Now()) cipherSeed, err := New(0, &testEntropy, time.Now())
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create seed: %v", err)
}
// Now that we have our cipher seed, we'll encipher it and request a // Now that we have our cipher seed, we'll encipher it and request a
// mnemonic that we can use to recover later. // mnemonic that we can use to recover later.
mnemonic, err := cipherSeed.ToMnemonic(pass) mnemonic, err := cipherSeed.ToMnemonic(pass)
if err != nil { require.NoError(t, err)
t.Fatalf("unable to create mnemonic: %v", err)
}
// We'll now swap out two words from the mnemonic, which should trigger // We'll now swap out two words from the mnemonic, which should trigger
// a checksum failure. // a checksum failure.
@@ -595,9 +506,7 @@ func TestDecipherIncorrectMnemonic(t *testing.T) {
// If we attempt to map back to the original cipher seed now, then we // If we attempt to map back to the original cipher seed now, then we
// should get ErrIncorrectMnemonic. // should get ErrIncorrectMnemonic.
_, err = mnemonic.ToCipherSeed(pass) _, err = mnemonic.ToCipherSeed(pass)
if err != ErrIncorrectMnemonic { require.Equal(t, ErrIncorrectMnemonic, err)
t.Fatalf("expected ErrIncorrectMnemonic error")
}
} }
// TODO(roasbeef): add test failure checksum fail is modified, new error // TODO(roasbeef): add test failure checksum fail is modified, new error