DeterministicKeyChain: use new HDPath::ancestors methods

This commit is contained in:
Sean Gilligan 2022-04-14 16:37:14 -07:00 committed by Andreas Schildbach
parent f500727729
commit 459df5fed0
3 changed files with 71 additions and 4 deletions

View file

@ -25,6 +25,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
@ -246,6 +247,27 @@ public class HDPath extends AbstractList<ChildNumber> {
return unmodifiableList;
}
/**
* Return a list of all ancestors of this path
* @return unmodifiable list of ancestors
*/
public List<HDPath> ancestors() {
return ancestors(false);
}
/**
* Return a list of all ancestors of this path
* @param includeSelf true if include path for self
* @return unmodifiable list of ancestors
*/
public List<HDPath> ancestors(boolean includeSelf) {
int endExclusive = unmodifiableList.size() + (includeSelf ? 1 : 0);
return IntStream.range(1, endExclusive)
.mapToObj(i -> unmodifiableList.subList(0, i))
.map(l -> HDPath.of(hasPrivateKey, l))
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}
@Override
public ChildNumber get(int index) {
return unmodifiableList.get(index);

View file

@ -370,8 +370,8 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
rootKey.setCreationTimeSeconds(seed.getCreationTimeSeconds());
basicKeyChain.importKey(rootKey);
hierarchy = new DeterministicHierarchy(rootKey);
for (int i = 1; i <= getAccountPath().size(); i++) {
basicKeyChain.importKey(hierarchy.get(getAccountPath().subList(0, i), false, true));
for (HDPath path : getAccountPath().ancestors(true)) {
basicKeyChain.importKey(hierarchy.get(path, false, true));
}
initializeHierarchyUnencrypted(rootKey);
}
@ -408,8 +408,8 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
hierarchy = new DeterministicHierarchy(rootKey);
basicKeyChain.importKey(rootKey);
for (int i = 1; i < getAccountPath().size(); i++) {
encryptNonLeaf(aesKey, chain, rootKey, getAccountPath().subList(0, i));
for (HDPath path : getAccountPath().ancestors()) {
encryptNonLeaf(aesKey, chain, rootKey, path);
}
DeterministicKey account = encryptNonLeaf(aesKey, chain, rootKey, getAccountPath());
externalParentKey = encryptNonLeaf(aesKey, chain, account, getAccountPath().extend(EXTERNAL_SUBPATH));

View file

@ -58,6 +58,51 @@ public class HDPathTest {
assertEquals("m/0H/1H/0H/1/0", path5.toString());
}
@Test
public void testAncestors() {
HDPath path = HDPath.parsePath("m/0H/1H/0H/1/0");
List<HDPath> ancestors = path.ancestors();
assertEquals(4, ancestors.size());
assertEquals(HDPath.parsePath("m/0H"), ancestors.get(0));
assertEquals(HDPath.parsePath("m/0H/1H"), ancestors.get(1));
assertEquals(HDPath.parsePath("m/0H/1H/0H"), ancestors.get(2));
assertEquals(HDPath.parsePath("m/0H/1H/0H/1"), ancestors.get(3));
List<HDPath> ancestorsWithSelf = path.ancestors(true);
assertEquals(5, ancestorsWithSelf.size());
assertEquals(HDPath.parsePath("m/0H"), ancestorsWithSelf.get(0));
assertEquals(HDPath.parsePath("m/0H/1H"), ancestorsWithSelf.get(1));
assertEquals(HDPath.parsePath("m/0H/1H/0H"), ancestorsWithSelf.get(2));
assertEquals(HDPath.parsePath("m/0H/1H/0H/1"), ancestorsWithSelf.get(3));
assertEquals(HDPath.parsePath("m/0H/1H/0H/1/0"), ancestorsWithSelf.get(4));
HDPath rootPath = HDPath.parsePath("m/0H");
List<HDPath> empty = rootPath.ancestors();
assertEquals(0, empty.size());
List<HDPath> self = rootPath.ancestors(true);
assertEquals(1, self.size());
assertEquals(rootPath, self.get(0));
HDPath emptyPath = HDPath.m();
List<HDPath> empty2 = emptyPath.ancestors();
assertEquals(0, empty2.size());
List<HDPath> empty3 = emptyPath.ancestors(true);
assertEquals(0, empty3.size());
}
@Test
public void testFormatPath() {
Object[] tv = {