/** @throws HDDerivationException if privKeyBytes is invalid (0 or >= n). */ public static DeterministicKey createMasterPrivKeyFromBytes(byte[] privKeyBytes, byte[] chainCode) throws HDDerivationException { BigInteger privateKeyFieldElt = HDUtils.toBigInteger(privKeyBytes); assertNonZero(privateKeyFieldElt, "Generated master key is invalid."); assertLessThanN(privateKeyFieldElt, "Generated master key is invalid."); return new DeterministicKey( ImmutableList.<ChildNumber>of(), chainCode, null, privateKeyFieldElt, null); }
/** * @throws HDDerivationException if private derivation is attempted for a public-only parent key, * or if the resulting derived key is invalid (eg. private key == 0). */ public static DeterministicKey deriveChildKey(DeterministicKey parent, ChildNumber childNumber) throws HDDerivationException { RawKeyBytes rawKey = deriveChildKeyBytes(parent, childNumber); return new DeterministicKey( HDUtils.append(parent.getChildNumberPath(), childNumber), rawKey.chainCode, parent.hasPrivate() ? null : HDUtils.getCurve().decodePoint(rawKey.keyBytes), parent.hasPrivate() ? HDUtils.toBigInteger(rawKey.keyBytes) : null, parent); }
private static RawKeyBytes deriveChildKeyBytes(DeterministicKey parent, ChildNumber childNumber) throws HDDerivationException { byte[] parentPublicKey = HDUtils.getBytes(parent.getPubPoint()); assert parentPublicKey.length == 33 : parentPublicKey.length; ByteBuffer data = ByteBuffer.allocate(37); if (childNumber.isPrivateDerivation()) { data.put(parent.getPrivKeyBytes33()); } else { data.put(parentPublicKey); } data.putInt(childNumber.getI()); byte[] i = HDUtils.hmacSha512(parent.getChainCode(), data.array()); assert i.length == 64 : i.length; byte[] il = Arrays.copyOfRange(i, 0, 32); byte[] chainCode = Arrays.copyOfRange(i, 32, 64); BigInteger ilInt = HDUtils.toBigInteger(il); assertLessThanN(ilInt, "Illegal derived key: I_L >= n"); byte[] keyBytes; final BigInteger privAsFieldElement = parent.getPrivAsFieldElement(); if (privAsFieldElement != null) { BigInteger ki = privAsFieldElement.add(ilInt).mod(HDUtils.getEcParams().getN()); assertNonZero(ki, "Illegal derived key: derived private key equals 0."); keyBytes = ki.toByteArray(); } else { checkArgument( !childNumber.isPrivateDerivation(), "Can't use private derivation with public keys only."); ECPoint Ki = HDUtils.getEcParams().getG().multiply(ilInt).add(parent.getPubPoint()); checkArgument( !Ki.equals(HDUtils.getCurve().getInfinity()), "Illegal derived key: derived public key equals infinity."); keyBytes = HDUtils.toCompressed(Ki.getEncoded()); } return new RawKeyBytes(keyBytes, chainCode); }