package com.blockstream.test;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.blockstream.libwally.Wally;
import static com.blockstream.libwally.Wally.BIP39_ENTROPY_LEN_256;
import static com.blockstream.libwally.Wally.BIP39_SEED_LEN_512;
public class test_mnemonic {
private final SecureRandom sr = new SecureRandom();
private final Object wl;
public test_mnemonic(final String lang) {
this.wl = Wally.bip39_get_wordlist(lang);
}
public static String[] getLanguages() {
return Wally.bip39_get_languages().split(" ");
}
public String generate(final int strength) {
final byte[] seed = new byte[strength];
sr.nextBytes(seed);
return toMnemonic(seed);
}
public String generate() {
return generate(BIP39_ENTROPY_LEN_256);
}
public byte[] toEntropy(final String mnemonics) {
final byte[] buf = new byte[BIP39_ENTROPY_LEN_256];
return Arrays.copyOf(buf, Wally.bip39_mnemonic_to_bytes(
wl, mnemonics, buf));
}
public String toMnemonic(final byte[] data) {
return Wally.bip39_mnemonic_from_bytes(wl, data);
}
public boolean check(final String mnemonic) {
try {
Wally.bip39_mnemonic_validate(wl, mnemonic);
return true;
} catch (final Exception e) {
return false;
}
}
public byte[] toSeed(final String mnemonic, final String passphrase) {
final byte[] buf = new byte[BIP39_SEED_LEN_512];
Wally.bip39_mnemonic_to_seed(mnemonic, passphrase, buf);
return buf;
}
private static final Map<String, byte[]> testMap;
static {
final String m =
"legal winner thank year wave sausage worth useful legal winner thank yellow";
final Map<String, byte[]> aMap = new HashMap<>();
aMap.put(m, new byte[]{});
aMap.put(m, null);
aMap.put("gibberish", new byte[BIP39_ENTROPY_LEN_256]);
aMap.put("", new byte[BIP39_ENTROPY_LEN_256]);
aMap.put(null, new byte[BIP39_ENTROPY_LEN_256]);
testMap = Collections.unmodifiableMap(aMap);
}
public static void main(final String[] args) {
for (final String lang : getLanguages()) {
final test_mnemonic m = new test_mnemonic(lang);
final String phrase = m.generate();
if (!m.check(phrase) ||
m.check(String.format("%s foo", phrase)) ||
!Arrays.equals(m.toEntropy(phrase), m.toEntropy(phrase)) ||
!m.toMnemonic(m.toEntropy(phrase)).equals(phrase) ||
Arrays.equals(m.toSeed(phrase, "foo"), m.toSeed(phrase, "bar")))
throw new RuntimeException("Mnemonic failed basic verification");
}
for(final Map.Entry<String, byte[]> entry : testMap.entrySet())
try {
Wally.bip39_mnemonic_to_bytes(null, entry.getKey(), entry.getValue());
throw new RuntimeException("Mnemonic failed basic verification");
} catch (final IllegalArgumentException e) {
// pass
}
final byte[] data = new byte[BIP39_ENTROPY_LEN_256];
try {
Wally.bip39_mnemonic_from_bytes(null, data);
throw new RuntimeException("Mnemonic failed basic verification");
} catch (final IllegalArgumentException e) {
// pass
}
try {
Wally.bip39_mnemonic_from_bytes(new Object(), data);
throw new RuntimeException("Mnemonic failed basic verification");
} catch (final IllegalArgumentException e) {
// pass
}
}
}