mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 14:54:15 +00:00
Rename ExtendedHierarchicKey to DeterministicKey. Add annotations and rewrite a bit of code to satisfy static analysis.
This commit is contained in:
parent
50dd5af0c8
commit
000d81d54f
@ -23,6 +23,7 @@ package com.google.bitcoin.crypto.hd;
|
||||
*/
|
||||
public class ChildNumber {
|
||||
public static final int PRIV_BIT = 0x80000000;
|
||||
public static final ChildNumber ZERO = new ChildNumber(0);
|
||||
|
||||
/** Integer i as per BIP 32 spec, including the MSB denoting derivation type (0 = public, 1 = private) **/
|
||||
private final int i;
|
||||
|
@ -31,7 +31,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
* Bitcoin's privacy system require new keys to be created for each transaction, but managing all these
|
||||
* keys quickly becomes unwieldy. In particular it becomes hard to back up and distribute them. By having
|
||||
* a way to derive random-looking but deterministic keys we can make wallet backup simpler and gain the
|
||||
* ability to hand out {@link ExtendedHierarchicKey}s to other people who can then create new addresses
|
||||
* ability to hand out {@link DeterministicKey}s to other people who can then create new addresses
|
||||
* on the fly, without having to contact us.</p>
|
||||
*
|
||||
* <p>The hierarchy is started from a single root key, and a location in the tree is given by a path which
|
||||
@ -44,7 +44,7 @@ public class DeterministicHierarchy implements Serializable {
|
||||
*/
|
||||
private static final int MAX_CHILD_DERIVATION_ATTEMPTS = 100;
|
||||
|
||||
private final Map<ImmutableList<ChildNumber>, ExtendedHierarchicKey> keys = Maps.newHashMap();
|
||||
private final Map<ImmutableList<ChildNumber>, DeterministicKey> keys = Maps.newHashMap();
|
||||
private final ImmutableList<ChildNumber> rootPath;
|
||||
private final Map<ImmutableList<ChildNumber>, ChildNumber> lastPrivDerivedNumbers = Maps.newHashMap();
|
||||
private final Map<ImmutableList<ChildNumber>, ChildNumber> lastPubDerivedNumbers = Maps.newHashMap();
|
||||
@ -53,12 +53,12 @@ public class DeterministicHierarchy implements Serializable {
|
||||
* Constructs a new hierarchy rooted at the given key. Note that this does not have to be the top of the tree.
|
||||
* You can construct a DeterministicHierarchy for a subtree of a larger tree that you may not own.
|
||||
*/
|
||||
public DeterministicHierarchy(ExtendedHierarchicKey rootKey) {
|
||||
public DeterministicHierarchy(DeterministicKey rootKey) {
|
||||
putKey(rootKey);
|
||||
rootPath = rootKey.getChildNumberPath();
|
||||
}
|
||||
|
||||
private void putKey(ExtendedHierarchicKey key) {
|
||||
private void putKey(DeterministicKey key) {
|
||||
keys.put(key.getChildNumberPath(), key);
|
||||
}
|
||||
|
||||
@ -71,14 +71,14 @@ public class DeterministicHierarchy implements Serializable {
|
||||
* @return next newly created key using the child derivation function
|
||||
* @throws IllegalArgumentException if create is false and the path was not found.
|
||||
*/
|
||||
public ExtendedHierarchicKey get(List<ChildNumber> path, boolean relativePath, boolean create) {
|
||||
public DeterministicKey get(List<ChildNumber> path, boolean relativePath, boolean create) {
|
||||
ImmutableList<ChildNumber> absolutePath = relativePath
|
||||
? ImmutableList.<ChildNumber>builder().addAll(rootPath).addAll(path).build()
|
||||
: ImmutableList.copyOf(path);
|
||||
if (!keys.containsKey(absolutePath)) {
|
||||
checkArgument(create, "No key found for {} path {}.", relativePath ? "relative" : "absolute", path);
|
||||
checkArgument(absolutePath.size() > 0, "Can't derive the master key: nothing to derive from.");
|
||||
ExtendedHierarchicKey parent = get(absolutePath.subList(0, absolutePath.size() - 1), relativePath, true);
|
||||
DeterministicKey parent = get(absolutePath.subList(0, absolutePath.size() - 1), relativePath, true);
|
||||
putKey(HDKeyDerivation.deriveChildKey(parent, absolutePath.get(absolutePath.size() - 1)));
|
||||
}
|
||||
return keys.get(absolutePath);
|
||||
@ -95,8 +95,8 @@ public class DeterministicHierarchy implements Serializable {
|
||||
* @return next newly created key using the child derivation funtcion
|
||||
* @throws IllegalArgumentException if the parent doesn't exist and createParent is false.
|
||||
*/
|
||||
public ExtendedHierarchicKey deriveNextChild(ImmutableList<ChildNumber> parentPath, boolean relative, boolean createParent, boolean privateDerivation) {
|
||||
ExtendedHierarchicKey parent = get(parentPath, relative, createParent);
|
||||
public DeterministicKey deriveNextChild(ImmutableList<ChildNumber> parentPath, boolean relative, boolean createParent, boolean privateDerivation) {
|
||||
DeterministicKey parent = get(parentPath, relative, createParent);
|
||||
int nAttempts = 0;
|
||||
while (nAttempts++ < MAX_CHILD_DERIVATION_ATTEMPTS) {
|
||||
try {
|
||||
@ -125,12 +125,12 @@ public class DeterministicHierarchy implements Serializable {
|
||||
* @return the requested key.
|
||||
* @throws IllegalArgumentException if the parent doesn't exist and createParent is false.
|
||||
*/
|
||||
public ExtendedHierarchicKey deriveChild(List<ChildNumber> parentPath, boolean relative, boolean createParent, ChildNumber createChildNumber) {
|
||||
public DeterministicKey deriveChild(List<ChildNumber> parentPath, boolean relative, boolean createParent, ChildNumber createChildNumber) {
|
||||
return deriveChild(get(parentPath, relative, createParent), createChildNumber);
|
||||
}
|
||||
|
||||
private ExtendedHierarchicKey deriveChild(ExtendedHierarchicKey parent, ChildNumber createChildNumber) {
|
||||
ExtendedHierarchicKey childKey = HDKeyDerivation.deriveChildKey(parent, createChildNumber);
|
||||
private DeterministicKey deriveChild(DeterministicKey parent, ChildNumber createChildNumber) {
|
||||
DeterministicKey childKey = HDKeyDerivation.deriveChildKey(parent, createChildNumber);
|
||||
putKey(childKey);
|
||||
return childKey;
|
||||
}
|
||||
@ -138,7 +138,7 @@ public class DeterministicHierarchy implements Serializable {
|
||||
/**
|
||||
* Returns the root key that the {@link DeterministicHierarchy} was created with.
|
||||
*/
|
||||
public ExtendedHierarchicKey getRootKey() {
|
||||
public DeterministicKey getRootKey() {
|
||||
return get(rootPath, false, false);
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import com.google.common.collect.Iterables;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -31,27 +32,30 @@ import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* An extended key is a node in a {@link DeterministicHierarchy}. As per
|
||||
* <a href="https://en.bitcoin.it/wiki/BIP_0032">the BIP 32 specification</a> it is a pair (key, chaincode). If you
|
||||
* know its path in the tree you can derive more keys from this.
|
||||
*/
|
||||
public class ExtendedHierarchicKey implements Serializable {
|
||||
public static final ChildNumber MASTER_CHILD_NUMBER = new ChildNumber(0);
|
||||
|
||||
public class DeterministicKey implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final Joiner PATH_JOINER = Joiner.on("/");
|
||||
|
||||
private final ExtendedHierarchicKey parent;
|
||||
private final DeterministicKey parent;
|
||||
private ECPoint publicAsPoint;
|
||||
private final BigInteger privateAsFieldElement;
|
||||
private final ImmutableList<ChildNumber> childNumberPath;
|
||||
|
||||
/** 32 bytes */
|
||||
private byte[] chainCode;
|
||||
private final byte[] chainCode;
|
||||
|
||||
ExtendedHierarchicKey(ImmutableList<ChildNumber> childNumberPath, byte[] chainCode, ECPoint publicAsPoint, BigInteger privateKeyFieldElt, ExtendedHierarchicKey parent) {
|
||||
assert chainCode.length == 32 : chainCode.length;
|
||||
DeterministicKey(ImmutableList<ChildNumber> childNumberPath, byte[] chainCode,
|
||||
@Nullable ECPoint publicAsPoint, @Nullable BigInteger privateKeyFieldElt,
|
||||
@Nullable DeterministicKey parent) {
|
||||
checkArgument(chainCode.length == 32);
|
||||
this.parent = parent;
|
||||
this.childNumberPath = childNumberPath;
|
||||
this.chainCode = Arrays.copyOf(chainCode, chainCode.length);
|
||||
@ -73,10 +77,10 @@ public class ExtendedHierarchicKey implements Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element of the path returned by {@link com.google.bitcoin.crypto.hd.ExtendedHierarchicKey#getChildNumberPath()}
|
||||
* Returns the last element of the path returned by {@link DeterministicKey#getChildNumberPath()}
|
||||
*/
|
||||
public ChildNumber getChildNumber() {
|
||||
return getDepth() == 0 ? MASTER_CHILD_NUMBER : childNumberPath.get(childNumberPath.size() - 1);
|
||||
return getDepth() == 0 ? ChildNumber.ZERO : childNumberPath.get(childNumberPath.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,7 +105,8 @@ public class ExtendedHierarchicKey implements Serializable {
|
||||
}
|
||||
|
||||
ECPoint getPubPoint() {
|
||||
if (publicAsPoint == null && privateAsFieldElement != null) {
|
||||
if (publicAsPoint == null) {
|
||||
checkNotNull(privateAsFieldElement);
|
||||
publicAsPoint = HDUtils.getEcParams().getG().multiply(privateAsFieldElement);
|
||||
}
|
||||
return HDUtils.compressedCopy(publicAsPoint);
|
||||
@ -118,14 +123,20 @@ public class ExtendedHierarchicKey implements Serializable {
|
||||
return Arrays.copyOfRange(getIdentifier(), 0, 4);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BigInteger getPrivAsFieldElement() {
|
||||
return privateAsFieldElement;
|
||||
}
|
||||
|
||||
public ExtendedHierarchicKey getParent() {
|
||||
@Nullable
|
||||
public DeterministicKey getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the private key bytes, if they were provided during construction.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] getPrivKeyBytes() {
|
||||
return privateAsFieldElement == null ? null : privateAsFieldElement.toByteArray();
|
||||
}
|
||||
@ -135,16 +146,18 @@ public class ExtendedHierarchicKey implements Serializable {
|
||||
*/
|
||||
public byte[] getPrivKeyBytes33() {
|
||||
byte[] bytes33 = new byte[33];
|
||||
byte[] priv = getPrivKeyBytes();
|
||||
byte[] priv = checkNotNull(getPrivKeyBytes(), "Private key missing");
|
||||
System.arraycopy(priv, 0, bytes33, 33 - priv.length, priv.length);
|
||||
return bytes33;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The same key with the private part removed. May return the same instance.
|
||||
* Returns the same key with the private part removed. May return the same instance.
|
||||
*/
|
||||
public ExtendedHierarchicKey getPubOnly() {
|
||||
return hasPrivate() ? new ExtendedHierarchicKey(getChildNumberPath(), getChainCode(), getPubPoint(), null, getParent() == null ? null : getParent().getPubOnly()) : this;
|
||||
public DeterministicKey getPubOnly() {
|
||||
if (!hasPrivate()) return this;
|
||||
final DeterministicKey parentPub = getParent() == null ? null : getParent().getPubOnly();
|
||||
return new DeterministicKey(getChildNumberPath(), getChainCode(), getPubPoint(), null, parentPub);
|
||||
}
|
||||
|
||||
public boolean hasPrivate() {
|
@ -43,7 +43,7 @@ public final class HDKeyDerivation {
|
||||
*
|
||||
* @throws HDDerivationException if generated master key is invalid (private key 0 or >= n).
|
||||
*/
|
||||
public static ExtendedHierarchicKey createMasterPrivateKey(byte[] seed) throws HDDerivationException {
|
||||
public static DeterministicKey createMasterPrivateKey(byte[] seed) throws HDDerivationException {
|
||||
// Calculate I = HMAC-SHA512(key="Bitcoin seed", msg=S)
|
||||
byte[] i = HDUtils.hmacSha256(MASTER_HMAC_SHA256, seed);
|
||||
// Split I into two 32-byte sequences, Il and Ir.
|
||||
@ -52,7 +52,7 @@ public final class HDKeyDerivation {
|
||||
byte[] il = Arrays.copyOfRange(i, 0, 32);
|
||||
byte[] ir = Arrays.copyOfRange(i, 32, 64);
|
||||
Arrays.fill(i, (byte)0);
|
||||
ExtendedHierarchicKey masterPrivKey = createMasterPrivKeyFromBytes(il, ir);
|
||||
DeterministicKey masterPrivKey = createMasterPrivKeyFromBytes(il, ir);
|
||||
Arrays.fill(il, (byte)0);
|
||||
Arrays.fill(ir, (byte)0);
|
||||
return masterPrivKey;
|
||||
@ -61,21 +61,21 @@ public final class HDKeyDerivation {
|
||||
/**
|
||||
* @throws HDDerivationException if privKeyBytes is invalid (0 or >= n).
|
||||
*/
|
||||
static ExtendedHierarchicKey createMasterPrivKeyFromBytes(byte[] privKeyBytes, byte[] chainCode) throws HDDerivationException {
|
||||
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 ExtendedHierarchicKey(ImmutableList.<ChildNumber>of(), chainCode, null, privateKeyFieldElt, null);
|
||||
return new DeterministicKey(ImmutableList.<ChildNumber>of(), chainCode, null, privateKeyFieldElt, null);
|
||||
}
|
||||
|
||||
public static ExtendedHierarchicKey createMasterPubKeyFromBytes(byte[] pubKeyBytes, byte[] chainCode) {
|
||||
return new ExtendedHierarchicKey(ImmutableList.<ChildNumber>of(), chainCode, HDUtils.getCurve().decodePoint(pubKeyBytes), null, null);
|
||||
public static DeterministicKey createMasterPubKeyFromBytes(byte[] pubKeyBytes, byte[] chainCode) {
|
||||
return new DeterministicKey(ImmutableList.<ChildNumber>of(), chainCode, HDUtils.getCurve().decodePoint(pubKeyBytes), null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param childNumber the "extended" child number, ie. with the 0x80000000 bit specifying private/public derivation.
|
||||
*/
|
||||
public static ExtendedHierarchicKey deriveChildKey(ExtendedHierarchicKey parent, int childNumber) {
|
||||
public static DeterministicKey deriveChildKey(DeterministicKey parent, int childNumber) {
|
||||
return deriveChildKey(parent, new ChildNumber(childNumber));
|
||||
}
|
||||
|
||||
@ -83,11 +83,11 @@ public final class HDKeyDerivation {
|
||||
* @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 ExtendedHierarchicKey deriveChildKey(ExtendedHierarchicKey parent, ChildNumber childNumber)
|
||||
public static DeterministicKey deriveChildKey(DeterministicKey parent, ChildNumber childNumber)
|
||||
throws HDDerivationException {
|
||||
|
||||
RawKeyBytes rawKey = deriveChildKeyBytes(parent, childNumber);
|
||||
return new ExtendedHierarchicKey(
|
||||
return new DeterministicKey(
|
||||
HDUtils.append(parent.getChildNumberPath(), childNumber),
|
||||
rawKey.chainCode,
|
||||
parent.hasPrivate() ? null : HDUtils.getCurve().decodePoint(rawKey.keyBytes),
|
||||
@ -95,7 +95,7 @@ public final class HDKeyDerivation {
|
||||
parent);
|
||||
}
|
||||
|
||||
private static RawKeyBytes deriveChildKeyBytes(ExtendedHierarchicKey parent, ChildNumber childNumber)
|
||||
private static RawKeyBytes deriveChildKeyBytes(DeterministicKey parent, ChildNumber childNumber)
|
||||
throws HDDerivationException {
|
||||
|
||||
byte[] parentPublicKey = HDUtils.getBytes(parent.getPubPoint());
|
||||
|
@ -126,7 +126,7 @@ public class BIP32Test {
|
||||
private void testVector(int testCase) throws AddressFormatException {
|
||||
log.info("======= Test vector {}", testCase);
|
||||
HDWTestVector tv = tvs[testCase];
|
||||
ExtendedHierarchicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(Hex.decode(tv.seed));
|
||||
DeterministicKey masterPrivateKey = HDKeyDerivation.createMasterPrivateKey(Hex.decode(tv.seed));
|
||||
Assert.assertEquals(testEncode(tv.priv), testEncode(masterPrivateKey.serializePrivB58()));
|
||||
Assert.assertEquals(testEncode(tv.pub), testEncode(masterPrivateKey.serializePubB58()));
|
||||
DeterministicHierarchy dh = new DeterministicHierarchy(masterPrivateKey);
|
||||
@ -135,7 +135,7 @@ public class BIP32Test {
|
||||
log.info("{}", tc.name);
|
||||
Assert.assertEquals(tc.name, String.format("Test%d %s", testCase + 1, tc.getPathDescription()));
|
||||
int depth = tc.path.length - 1;
|
||||
ExtendedHierarchicKey ehkey = dh.deriveChild(Arrays.asList(tc.path).subList(0, depth), false, true, tc.path[depth]);
|
||||
DeterministicKey ehkey = dh.deriveChild(Arrays.asList(tc.path).subList(0, depth), false, true, tc.path[depth]);
|
||||
Assert.assertEquals(testEncode(tc.priv), testEncode(ehkey.serializePrivB58()));
|
||||
Assert.assertEquals(testEncode(tc.pub), testEncode(ehkey.serializePubB58()));
|
||||
}
|
||||
|
@ -53,56 +53,56 @@ public class ChildKeyDerivationTest {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Start with an extended PRIVATE key
|
||||
ExtendedHierarchicKey ekprv = HDKeyDerivation.createMasterPrivKeyFromBytes(priv, chain);
|
||||
DeterministicKey ekprv = HDKeyDerivation.createMasterPrivKeyFromBytes(priv, chain);
|
||||
|
||||
// Create two accounts
|
||||
ExtendedHierarchicKey ekprv_0 = HDKeyDerivation.deriveChildKey(ekprv, 0);
|
||||
ExtendedHierarchicKey ekprv_1 = HDKeyDerivation.deriveChildKey(ekprv, 1);
|
||||
DeterministicKey ekprv_0 = HDKeyDerivation.deriveChildKey(ekprv, 0);
|
||||
DeterministicKey ekprv_1 = HDKeyDerivation.deriveChildKey(ekprv, 1);
|
||||
|
||||
// Create internal and external chain on Account 0
|
||||
ExtendedHierarchicKey ekprv_0_EX = HDKeyDerivation.deriveChildKey(ekprv_0, HDW_CHAIN_EXTERNAL);
|
||||
ExtendedHierarchicKey ekprv_0_IN = HDKeyDerivation.deriveChildKey(ekprv_0, HDW_CHAIN_INTERNAL);
|
||||
DeterministicKey ekprv_0_EX = HDKeyDerivation.deriveChildKey(ekprv_0, HDW_CHAIN_EXTERNAL);
|
||||
DeterministicKey ekprv_0_IN = HDKeyDerivation.deriveChildKey(ekprv_0, HDW_CHAIN_INTERNAL);
|
||||
|
||||
// Create three addresses on external chain
|
||||
ExtendedHierarchicKey ekprv_0_EX_0 = HDKeyDerivation.deriveChildKey(ekprv_0_EX, 0);
|
||||
ExtendedHierarchicKey ekprv_0_EX_1 = HDKeyDerivation.deriveChildKey(ekprv_0_EX, 1);
|
||||
ExtendedHierarchicKey ekprv_0_EX_2 = HDKeyDerivation.deriveChildKey(ekprv_0_EX, 2);
|
||||
DeterministicKey ekprv_0_EX_0 = HDKeyDerivation.deriveChildKey(ekprv_0_EX, 0);
|
||||
DeterministicKey ekprv_0_EX_1 = HDKeyDerivation.deriveChildKey(ekprv_0_EX, 1);
|
||||
DeterministicKey ekprv_0_EX_2 = HDKeyDerivation.deriveChildKey(ekprv_0_EX, 2);
|
||||
|
||||
// Create three addresses on internal chain
|
||||
ExtendedHierarchicKey ekprv_0_IN_0 = HDKeyDerivation.deriveChildKey(ekprv_0_IN, 0);
|
||||
ExtendedHierarchicKey ekprv_0_IN_1 = HDKeyDerivation.deriveChildKey(ekprv_0_IN, 1);
|
||||
ExtendedHierarchicKey ekprv_0_IN_2 = HDKeyDerivation.deriveChildKey(ekprv_0_IN, 2);
|
||||
DeterministicKey ekprv_0_IN_0 = HDKeyDerivation.deriveChildKey(ekprv_0_IN, 0);
|
||||
DeterministicKey ekprv_0_IN_1 = HDKeyDerivation.deriveChildKey(ekprv_0_IN, 1);
|
||||
DeterministicKey ekprv_0_IN_2 = HDKeyDerivation.deriveChildKey(ekprv_0_IN, 2);
|
||||
|
||||
// Now add a few more addresses with very large indices
|
||||
ExtendedHierarchicKey ekprv_1_IN = HDKeyDerivation.deriveChildKey(ekprv_1, HDW_CHAIN_INTERNAL);
|
||||
ExtendedHierarchicKey ekprv_1_IN_4095 = HDKeyDerivation.deriveChildKey(ekprv_1_IN, 4095);
|
||||
DeterministicKey ekprv_1_IN = HDKeyDerivation.deriveChildKey(ekprv_1, HDW_CHAIN_INTERNAL);
|
||||
DeterministicKey ekprv_1_IN_4095 = HDKeyDerivation.deriveChildKey(ekprv_1_IN, 4095);
|
||||
// ExtendedHierarchicKey ekprv_1_IN_4bil = HDKeyDerivation.deriveChildKey(ekprv_1_IN, 4294967295L);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Repeat the above with PUBLIC key
|
||||
ExtendedHierarchicKey ekpub = HDKeyDerivation.createMasterPubKeyFromBytes(HDUtils.toCompressed(pub), chain);
|
||||
DeterministicKey ekpub = HDKeyDerivation.createMasterPubKeyFromBytes(HDUtils.toCompressed(pub), chain);
|
||||
|
||||
// Create two accounts
|
||||
ExtendedHierarchicKey ekpub_0 = HDKeyDerivation.deriveChildKey(ekpub, 0);
|
||||
ExtendedHierarchicKey ekpub_1 = HDKeyDerivation.deriveChildKey(ekpub, 1);
|
||||
DeterministicKey ekpub_0 = HDKeyDerivation.deriveChildKey(ekpub, 0);
|
||||
DeterministicKey ekpub_1 = HDKeyDerivation.deriveChildKey(ekpub, 1);
|
||||
|
||||
// Create internal and external chain on Account 0
|
||||
ExtendedHierarchicKey ekpub_0_EX = HDKeyDerivation.deriveChildKey(ekpub_0, HDW_CHAIN_EXTERNAL);
|
||||
ExtendedHierarchicKey ekpub_0_IN = HDKeyDerivation.deriveChildKey(ekpub_0, HDW_CHAIN_INTERNAL);
|
||||
DeterministicKey ekpub_0_EX = HDKeyDerivation.deriveChildKey(ekpub_0, HDW_CHAIN_EXTERNAL);
|
||||
DeterministicKey ekpub_0_IN = HDKeyDerivation.deriveChildKey(ekpub_0, HDW_CHAIN_INTERNAL);
|
||||
|
||||
// Create three addresses on external chain
|
||||
ExtendedHierarchicKey ekpub_0_EX_0 = HDKeyDerivation.deriveChildKey(ekpub_0_EX, 0);
|
||||
ExtendedHierarchicKey ekpub_0_EX_1 = HDKeyDerivation.deriveChildKey(ekpub_0_EX, 1);
|
||||
ExtendedHierarchicKey ekpub_0_EX_2 = HDKeyDerivation.deriveChildKey(ekpub_0_EX, 2);
|
||||
DeterministicKey ekpub_0_EX_0 = HDKeyDerivation.deriveChildKey(ekpub_0_EX, 0);
|
||||
DeterministicKey ekpub_0_EX_1 = HDKeyDerivation.deriveChildKey(ekpub_0_EX, 1);
|
||||
DeterministicKey ekpub_0_EX_2 = HDKeyDerivation.deriveChildKey(ekpub_0_EX, 2);
|
||||
|
||||
// Create three addresses on internal chain
|
||||
ExtendedHierarchicKey ekpub_0_IN_0 = HDKeyDerivation.deriveChildKey(ekpub_0_IN, 0);
|
||||
ExtendedHierarchicKey ekpub_0_IN_1 = HDKeyDerivation.deriveChildKey(ekpub_0_IN, 1);
|
||||
ExtendedHierarchicKey ekpub_0_IN_2 = HDKeyDerivation.deriveChildKey(ekpub_0_IN, 2);
|
||||
DeterministicKey ekpub_0_IN_0 = HDKeyDerivation.deriveChildKey(ekpub_0_IN, 0);
|
||||
DeterministicKey ekpub_0_IN_1 = HDKeyDerivation.deriveChildKey(ekpub_0_IN, 1);
|
||||
DeterministicKey ekpub_0_IN_2 = HDKeyDerivation.deriveChildKey(ekpub_0_IN, 2);
|
||||
|
||||
// Now add a few more addresses with very large indices
|
||||
ExtendedHierarchicKey ekpub_1_IN = HDKeyDerivation.deriveChildKey(ekpub_1, HDW_CHAIN_INTERNAL);
|
||||
ExtendedHierarchicKey ekpub_1_IN_4095 = HDKeyDerivation.deriveChildKey(ekpub_1_IN, 4095);
|
||||
DeterministicKey ekpub_1_IN = HDKeyDerivation.deriveChildKey(ekpub_1, HDW_CHAIN_INTERNAL);
|
||||
DeterministicKey ekpub_1_IN_4095 = HDKeyDerivation.deriveChildKey(ekpub_1_IN, 4095);
|
||||
// ExtendedHierarchicKey ekpub_1_IN_4bil = HDKeyDerivation.deriveChildKey(ekpub_1_IN, 4294967295L);
|
||||
|
||||
assertEquals(hexEncodePub(ekprv.getPubOnly()), hexEncodePub(ekpub));
|
||||
@ -121,7 +121,7 @@ public class ChildKeyDerivationTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static String hexEncodePub(ExtendedHierarchicKey pubKey) {
|
||||
private static String hexEncodePub(DeterministicKey pubKey) {
|
||||
return hexEncode(pubKey.getPubKeyBytes());
|
||||
}
|
||||
|
||||
|
@ -30,10 +30,10 @@ public class DeterministicHierarchyTest {
|
||||
*/
|
||||
@Test
|
||||
public void testHierarchy() throws Exception {
|
||||
ExtendedHierarchicKey m = HDKeyDerivation.createMasterPrivateKey(new SecureRandom().generateSeed(32));
|
||||
DeterministicKey m = HDKeyDerivation.createMasterPrivateKey(new SecureRandom().generateSeed(32));
|
||||
|
||||
for (int iWallet = 0; iWallet < 3; iWallet++) {
|
||||
ExtendedHierarchicKey walletRootKey = HDKeyDerivation.deriveChildKey(m, iWallet);
|
||||
DeterministicKey walletRootKey = HDKeyDerivation.deriveChildKey(m, iWallet);
|
||||
DeterministicKeyGenerator hdWalletKeyGen = new DeterministicKeyGenerator(walletRootKey);
|
||||
assertEquals(walletRootKey.getChildNumber().getChildNumber(), iWallet);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user