private Bip32ECKeyPair deriveChildKey(int childNumber) { if (!hasPrivateKey()) { byte[] parentPublicKey = getPublicKeyPoint().getEncoded(true); ByteBuffer data = ByteBuffer.allocate(37); data.put(parentPublicKey); data.putInt(childNumber); byte[] i = hmacSha512(getChainCode(), data.array()); byte[] il = Arrays.copyOfRange(i, 0, 32); byte[] chainCode = Arrays.copyOfRange(i, 32, 64); BigInteger ilInt = new BigInteger(1, il); Arrays.fill(il, (byte) 0); ECPoint ki = Sign.publicPointFromPrivate(ilInt).add(getPublicKeyPoint()); return new Bip32ECKeyPair(null, Sign.publicFromPoint(ki.getEncoded(true)), childNumber, chainCode, this); } else { ByteBuffer data = ByteBuffer.allocate(37); if (isHardened(childNumber)) { data.put(getPrivateKeyBytes33()); } else { byte[] parentPublicKey = getPublicKeyPoint().getEncoded(true); data.put(parentPublicKey); byte[] i = hmacSha512(getChainCode(), data.array()); byte[] il = Arrays.copyOfRange(i, 0, 32); byte[] chainCode = Arrays.copyOfRange(i, 32, 64); BigInteger ilInt = new BigInteger(1, il);
public byte[] getPrivateKeyBytes33() { final int numBytes = 33; byte[] bytes33 = new byte[numBytes]; byte[] priv = bigIntegerToBytes32(getPrivateKey()); System.arraycopy(priv, 0, bytes33, numBytes - priv.length, priv.length); return bytes33; }
public static Bip32ECKeyPair generateKeyPair(byte[] seed) { byte[] i = hmacSha512("Bitcoin seed".getBytes(), seed); byte[] il = Arrays.copyOfRange(i, 0, 32); byte[] ir = Arrays.copyOfRange(i, 32, 64); Arrays.fill(i, (byte) 0); Bip32ECKeyPair keypair = Bip32ECKeyPair.create(il, ir); Arrays.fill(il, (byte) 0); Arrays.fill(ir, (byte) 0); return keypair; }
public Bip32ECKeyPair(BigInteger privateKey, BigInteger publicKey, int childNumber, byte[] chainCode, Bip32ECKeyPair parent) { super(privateKey, publicKey); this.parentHasPrivate = parent != null && parent.hasPrivateKey(); this.childNumber = childNumber; this.depth = parent == null ? 0 : parent.depth + 1; this.chainCode = Arrays.copyOf(chainCode, chainCode.length); this.parentFingerprint = parent != null ? parent.getFingerprint() : 0; }
private static byte[] serialize(Bip32ECKeyPair pair, int header, boolean pub) { ByteBuffer ser = ByteBuffer.allocate(78); ser.putInt(header); ser.put((byte) pair.getDepth()); ser.putInt(pair.getParentFingerprint()); ser.putInt(pair.getChildNumber()); ser.put(pair.getChainCode()); ser.put(pub ? pair.getPublicKeyPoint().getEncoded(true) : pair.getPrivateKeyBytes33()); return ser.array(); } }
public static Credentials loadBip44Credentials(String password, String mnemonic, boolean testNet) { byte[] seed = MnemonicUtils.generateSeed(mnemonic, password); Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed); Bip32ECKeyPair bip44Keypair = generateBip44KeyPair(masterKeypair, testNet); return Credentials.create(bip44Keypair); } }
private void testGenerated(String seed, String expectedPriv, String expectedPub, int[] path) { Bip32ECKeyPair pair = Bip32ECKeyPair.generateKeyPair(Numeric.hexStringToByteArray(seed)); assertNotNull(pair); pair = Bip32ECKeyPair.deriveKeyPair(pair, path); assertNotNull(pair); assertEquals(expectedPriv, Base58.encode(addChecksum(serializePrivate(pair)))); assertEquals(expectedPub, Base58.encode(addChecksum(serializePublic(pair)))); }
private byte[] getIdentifier() { return sha256hash160(getPublicKeyPoint().getEncoded(true)); }
public static Bip32ECKeyPair deriveKeyPair(Bip32ECKeyPair master, int[] path) { Bip32ECKeyPair curr = master; if (path != null) { for (int childNumber : path) { curr = curr.deriveChildKey(childNumber); } } return curr; }
public static Bip32ECKeyPair create(BigInteger privateKey, byte[] chainCode) { return new Bip32ECKeyPair(privateKey, Sign.publicKeyFromPrivate(privateKey), 0, chainCode, null); }
public static Bip32ECKeyPair generateBip44KeyPair(Bip32ECKeyPair master, boolean testNet) { if (testNet) { // /m/44'/0'/0 final int[] path = {44 | HARDENED_BIT, 0 | HARDENED_BIT, 0 | HARDENED_BIT, 0}; return Bip32ECKeyPair.deriveKeyPair(master, path); } else { // m/44'/60'/0'/0 final int[] path = {44 | HARDENED_BIT, 60 | HARDENED_BIT, 0 | HARDENED_BIT, 0}; return Bip32ECKeyPair.deriveKeyPair(master, path); } }
/** * Generates a BIP-44 compatible Ethereum wallet on top of BIP-39 generated seed. * * @param password Will be used for both wallet encryption and passphrase for BIP-39 seed * @param destinationDirectory The directory containing the wallet * @param testNet should use the testNet derive path * @return A BIP-39 compatible Ethereum wallet * @throws CipherException if the underlying cipher is not available * @throws IOException if the destination cannot be written to */ public static Bip39Wallet generateBip44Wallet(String password, File destinationDirectory, boolean testNet) throws CipherException, IOException { byte[] initialEntropy = new byte[16]; SecureRandomUtils.secureRandom().nextBytes(initialEntropy); String mnemonic = MnemonicUtils.generateMnemonic(initialEntropy); byte[] seed = MnemonicUtils.generateSeed(mnemonic, null); Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed); Bip32ECKeyPair bip44Keypair = generateBip44KeyPair(masterKeypair, testNet); String walletFile = generateWalletFile(password, bip44Keypair, destinationDirectory, false); return new Bip39Wallet(walletFile, mnemonic); }
public Bip32ECKeyPair(BigInteger privateKey, BigInteger publicKey, int childNumber, byte[] chainCode, Bip32ECKeyPair parent) { super(privateKey, publicKey); this.parentHasPrivate = parent != null && parent.hasPrivateKey(); this.childNumber = childNumber; this.depth = parent == null ? 0 : parent.depth + 1; this.chainCode = Arrays.copyOf(chainCode, chainCode.length); this.parentFingerprint = parent != null ? parent.getFingerprint() : 0; }
private byte[] getIdentifier() { return sha256hash160(getPublicKeyPoint().getEncoded(true)); }
public static Bip32ECKeyPair deriveKeyPair(Bip32ECKeyPair master, int[] path) { Bip32ECKeyPair curr = master; if (path != null) { for (int childNumber : path) { curr = curr.deriveChildKey(childNumber); } } return curr; }
public static Bip32ECKeyPair create(BigInteger privateKey, byte[] chainCode) { return new Bip32ECKeyPair(privateKey, Sign.publicKeyFromPrivate(privateKey), 0, chainCode, null); }
private Bip32ECKeyPair deriveChildKey(int childNumber) { if (!hasPrivateKey()) { byte[] parentPublicKey = getPublicKeyPoint().getEncoded(true); ByteBuffer data = ByteBuffer.allocate(37); data.put(parentPublicKey); data.putInt(childNumber); byte[] i = hmacSha512(getChainCode(), data.array()); byte[] il = Arrays.copyOfRange(i, 0, 32); byte[] chainCode = Arrays.copyOfRange(i, 32, 64); BigInteger ilInt = new BigInteger(1, il); Arrays.fill(il, (byte) 0); ECPoint ki = Sign.publicPointFromPrivate(ilInt).add(getPublicKeyPoint()); return new Bip32ECKeyPair(null, Sign.publicFromPoint(ki.getEncoded(true)), childNumber, chainCode, this); } else { ByteBuffer data = ByteBuffer.allocate(37); if (isHardened(childNumber)) { data.put(getPrivateKeyBytes33()); } else { byte[] parentPublicKey = getPublicKeyPoint().getEncoded(true); data.put(parentPublicKey); byte[] i = hmacSha512(getChainCode(), data.array()); byte[] il = Arrays.copyOfRange(i, 0, 32); byte[] chainCode = Arrays.copyOfRange(i, 32, 64); BigInteger ilInt = new BigInteger(1, il);
@Test public void testGenerateBip44Wallets() throws Exception { Bip39Wallet wallet = Bip44WalletUtils.generateBip44Wallet(PASSWORD, tempDir); byte[] seed = MnemonicUtils.generateSeed(wallet.getMnemonic(), PASSWORD); Bip32ECKeyPair masterKeypair = Bip32ECKeyPair.generateKeyPair(seed); Bip32ECKeyPair bip44Keypair = Bip44WalletUtils.generateBip44KeyPair(masterKeypair); Credentials credentials = Credentials.create(bip44Keypair); assertEquals(credentials, Bip44WalletUtils.loadBip44Credentials(PASSWORD, wallet.getMnemonic())); }
public byte[] getPrivateKeyBytes33() { final int numBytes = 33; byte[] bytes33 = new byte[numBytes]; byte[] priv = bigIntegerToBytes32(getPrivateKey()); System.arraycopy(priv, 0, bytes33, numBytes - priv.length, priv.length); return bytes33; }
public static Bip32ECKeyPair create(byte[] privateKey, byte[] chainCode) { return create(Numeric.toBigInt(privateKey), chainCode); }