Narrow pkg/cbk to keypair derivation
Remove KeyFromHex, Seal, and Open with their errors and constants. The library only derives crypto_box keypairs from BIP39 mnemonics; callers use golang.org/x/crypto/nacl/box directly for everything else.
This commit is contained in:
+20
-96
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/nacl/box"
|
||||
|
||||
"sneak.berlin/go/x/pkg/bip39wordlist"
|
||||
"sneak.berlin/go/x/pkg/cbk"
|
||||
@@ -83,6 +82,25 @@ func TestNewPassphraseChangesKeys(t *testing.T) {
|
||||
assert.Equal(t, withExtraWord, again, "derivation is deterministic")
|
||||
}
|
||||
|
||||
func TestNewDifferentMnemonicsGiveDifferentKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
first, err := bip39wordlist.GenerateMnemonic(bip39wordlist.MaxWordCount)
|
||||
require.NoError(t, err)
|
||||
|
||||
second, err := bip39wordlist.GenerateMnemonic(bip39wordlist.MaxWordCount)
|
||||
require.NoError(t, err)
|
||||
|
||||
firstKeypair, err := cbk.FromMnemonic(first)
|
||||
require.NoError(t, err)
|
||||
|
||||
secondKeypair, err := cbk.FromMnemonic(second)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEqual(t, firstKeypair.PublicKey, secondKeypair.PublicKey)
|
||||
assert.NotEqual(t, firstKeypair.PrivateKey, secondKeypair.PrivateKey)
|
||||
}
|
||||
|
||||
func TestNewRejectsInvalidMnemonic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -105,99 +123,5 @@ func TestKeyAccessors(t *testing.T) {
|
||||
assert.Len(t, keypair.PrivateKeyBytes(), cbk.KeySize)
|
||||
assert.Equal(t, keypair.PublicKey.Hex(), keypair.PublicKeyHex())
|
||||
assert.Equal(t, keypair.PrivateKey.Hex(), keypair.PrivateKeyHex())
|
||||
}
|
||||
|
||||
func TestKeyFromHexRoundTrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
keypair, err := cbk.FromMnemonic(vectorMnemonic())
|
||||
require.NoError(t, err)
|
||||
|
||||
parsed, err := cbk.KeyFromHex(keypair.PublicKeyHex())
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, keypair.PublicKey, parsed)
|
||||
}
|
||||
|
||||
func TestKeyFromHexRejectsBadInput(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := cbk.KeyFromHex("abcd")
|
||||
require.ErrorIs(t, err, cbk.ErrInvalidKeyHex)
|
||||
|
||||
notHex := "zz" + keypairForTest(t).PublicKeyHex()[2:]
|
||||
|
||||
_, err = cbk.KeyFromHex(notHex)
|
||||
require.ErrorIs(t, err, cbk.ErrInvalidKeyHex)
|
||||
}
|
||||
|
||||
func TestSealOpenRoundTrip(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
alice := keypairForTest(t)
|
||||
bob := keypairForTest(t)
|
||||
message := []byte("the quick brown fox jumps over the lazy dog")
|
||||
|
||||
sealed, err := alice.Seal(message, bob.PublicKey)
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, sealed, cbk.NonceSize+len(message)+box.Overhead)
|
||||
|
||||
opened, err := bob.Open(sealed, alice.PublicKey)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, message, opened)
|
||||
}
|
||||
|
||||
func TestSealUsesFreshNonces(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
alice := keypairForTest(t)
|
||||
bob := keypairForTest(t)
|
||||
message := []byte("same message twice")
|
||||
|
||||
first, err := alice.Seal(message, bob.PublicKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
second, err := alice.Seal(message, bob.PublicKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEqual(t, first, second)
|
||||
}
|
||||
|
||||
func TestOpenRejectsTamperingAndWrongKeys(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
alice := keypairForTest(t)
|
||||
bob := keypairForTest(t)
|
||||
eve := keypairForTest(t)
|
||||
message := []byte("for bob only")
|
||||
|
||||
sealed, err := alice.Seal(message, bob.PublicKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = eve.Open(sealed, alice.PublicKey)
|
||||
require.ErrorIs(t, err, cbk.ErrOpenFailed, "wrong recipient")
|
||||
|
||||
_, err = bob.Open(sealed, eve.PublicKey)
|
||||
require.ErrorIs(t, err, cbk.ErrOpenFailed, "wrong sender")
|
||||
|
||||
tampered := append([]byte(nil), sealed...)
|
||||
tampered[len(tampered)-1] ^= 0x01
|
||||
|
||||
_, err = bob.Open(tampered, alice.PublicKey)
|
||||
require.ErrorIs(t, err, cbk.ErrOpenFailed, "modified ciphertext")
|
||||
|
||||
_, err = bob.Open(sealed[:cbk.NonceSize-1], alice.PublicKey)
|
||||
require.ErrorIs(t, err, cbk.ErrSealedTooShort)
|
||||
}
|
||||
|
||||
// keypairForTest derives a keypair from a freshly generated mnemonic.
|
||||
func keypairForTest(t *testing.T) cbk.CryptoBoxKeypair {
|
||||
t.Helper()
|
||||
|
||||
mnemonic, err := bip39wordlist.GenerateMnemonic(bip39wordlist.MaxWordCount)
|
||||
require.NoError(t, err)
|
||||
|
||||
keypair, err := cbk.FromMnemonic(mnemonic)
|
||||
require.NoError(t, err)
|
||||
|
||||
return keypair
|
||||
assert.Len(t, keypair.PublicKeyHex(), 2*cbk.KeySize)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user