mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-15 20:07:19 +00:00
relax assumption that HD seeds are 128 bits
This commit is contained in:
@@ -76,6 +76,7 @@ import static com.google.common.collect.Lists.newLinkedList;
|
||||
*/
|
||||
public class DeterministicKeyChain implements EncryptableKeyChain {
|
||||
private static final Logger log = LoggerFactory.getLogger(DeterministicKeyChain.class);
|
||||
public static final int DEFAULT_SEED_BITS = 128;
|
||||
private final ReentrantLock lock = Threading.lock("DeterministicKeyChain");
|
||||
|
||||
private DeterministicHierarchy hierarchy;
|
||||
@@ -123,12 +124,12 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
||||
* Generates a new key chain with a 128 bit seed selected randomly from the given {@link java.security.SecureRandom}
|
||||
* object.
|
||||
*/
|
||||
public DeterministicKeyChain(SecureRandom random) {
|
||||
this(getRandomSeed(random), Utils.currentTimeSeconds());
|
||||
public DeterministicKeyChain(SecureRandom random, int bits) {
|
||||
this(getRandomSeed(random, bits), Utils.currentTimeSeconds());
|
||||
}
|
||||
|
||||
private static byte[] getRandomSeed(SecureRandom random) {
|
||||
byte[] seed = new byte[128 / 8];
|
||||
private static byte[] getRandomSeed(SecureRandom random, int bits) {
|
||||
byte[] seed = new byte[bits / 8];
|
||||
random.nextBytes(seed);
|
||||
return seed;
|
||||
}
|
||||
|
||||
@@ -62,6 +62,10 @@ import static com.google.common.base.Preconditions.*;
|
||||
*/
|
||||
public class KeyChainGroup {
|
||||
private static final Logger log = LoggerFactory.getLogger(KeyChainGroup.class);
|
||||
|
||||
/** Default and minimum length of HD seed, in bits */
|
||||
public static final int DEFAULT_SEED_BITS = 128;
|
||||
|
||||
private BasicKeyChain basic;
|
||||
private NetworkParameters params;
|
||||
private final List<DeterministicKeyChain> chains;
|
||||
@@ -187,7 +191,7 @@ public class KeyChainGroup {
|
||||
/** Adds a new HD chain to the chains list, and make it the default chain (from which keys are issued). */
|
||||
public void createAndActivateNewHDChain() {
|
||||
// We can't do auto upgrade here because we don't know the rotation time, if any.
|
||||
final DeterministicKeyChain chain = new DeterministicKeyChain(new SecureRandom());
|
||||
final DeterministicKeyChain chain = new DeterministicKeyChain(new SecureRandom(), DEFAULT_SEED_BITS);
|
||||
log.info("Creating and activating a new HD chain: {}", chain);
|
||||
for (ListenerRegistration<KeyChainEventListener> registration : basic.getListeners())
|
||||
chain.addEventListener(registration.listener, registration.executor);
|
||||
@@ -732,12 +736,12 @@ public class KeyChainGroup {
|
||||
log.info("Auto-upgrading pre-HD wallet using oldest non-rotating private key");
|
||||
byte[] seed = checkNotNull(keyToUse.getSecretBytes());
|
||||
// Private keys should be at least 128 bits long.
|
||||
checkState(seed.length >= 128 / 8);
|
||||
checkState(seed.length >= DEFAULT_SEED_BITS / 8);
|
||||
// We reduce the entropy here to 128 bits because people like to write their seeds down on paper, and 128
|
||||
// bits should be sufficient forever unless the laws of the universe change or ECC is broken; in either case
|
||||
// we all have bigger problems.
|
||||
seed = Arrays.copyOfRange(seed, 0, 128 / 8); // final argument is exclusive range.
|
||||
checkState(seed.length == 128 / 8);
|
||||
seed = Arrays.copyOfRange(seed, 0, DEFAULT_SEED_BITS / 8); // final argument is exclusive range.
|
||||
checkState(seed.length == DEFAULT_SEED_BITS / 8);
|
||||
DeterministicKeyChain chain = new DeterministicKeyChain(seed, keyToUse.getCreationTimeSeconds());
|
||||
if (aesKey != null) {
|
||||
chain = chain.toEncrypted(checkNotNull(basic.getKeyCrypter()), aesKey);
|
||||
|
||||
@@ -121,7 +121,7 @@ public class DeterministicKeyChainTest {
|
||||
public void random() {
|
||||
// Can't test much here but verify the constructor worked and the class is functional. The other tests rely on
|
||||
// a fixed seed to be deterministic.
|
||||
chain = new DeterministicKeyChain(new SecureRandom());
|
||||
chain = new DeterministicKeyChain(new SecureRandom(), 384);
|
||||
chain.setLookaheadSize(10);
|
||||
chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS).sign(Sha256Hash.ZERO_HASH);
|
||||
chain.getKey(KeyChain.KeyPurpose.CHANGE).sign(Sha256Hash.ZERO_HASH);
|
||||
|
||||
Reference in New Issue
Block a user