mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-02-24 22:58:32 +01:00
Remove support for mnemonic-less keychains
This commit is contained in:
parent
2fae12064c
commit
fec6cbc7df
9 changed files with 276 additions and 358 deletions
|
@ -80,6 +80,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 String DEFAULT_PASSPHRASE_FOR_MNEMONIC = "";
|
||||
|
||||
private final ReentrantLock lock = Threading.lock("DeterministicKeyChain");
|
||||
|
||||
|
@ -129,7 +130,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
* object and the default entropy size.
|
||||
*/
|
||||
public DeterministicKeyChain(SecureRandom random) {
|
||||
this(random, DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS, "", Utils.currentTimeSeconds());
|
||||
this(random, DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS, DEFAULT_PASSPHRASE_FOR_MNEMONIC, Utils.currentTimeSeconds());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,7 +138,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
* object and of the requested size in bits.
|
||||
*/
|
||||
public DeterministicKeyChain(SecureRandom random, int bits) {
|
||||
this(random, bits, "", Utils.currentTimeSeconds());
|
||||
this(random, bits, DEFAULT_PASSPHRASE_FOR_MNEMONIC, Utils.currentTimeSeconds());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,8 +155,8 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
* if the starting seed is the same. You should provide the creation time in seconds since the UNIX epoch for the
|
||||
* seed: this lets us know from what part of the chain we can expect to see derived keys appear.
|
||||
*/
|
||||
public DeterministicKeyChain(byte[] seed, long seedCreationTimeSecs) {
|
||||
this(new DeterministicSeed(seed, seedCreationTimeSecs));
|
||||
public DeterministicKeyChain(byte[] entropy, String passphrase, long seedCreationTimeSecs) {
|
||||
this(new DeterministicSeed(entropy, passphrase, seedCreationTimeSecs));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -224,7 +225,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
this.seed = seed;
|
||||
basicKeyChain = new BasicKeyChain(crypter);
|
||||
if (!seed.isEncrypted()) {
|
||||
rootKey = HDKeyDerivation.createMasterPrivateKey(checkNotNull(seed.getSecretBytes()));
|
||||
rootKey = HDKeyDerivation.createMasterPrivateKey(checkNotNull(seed.getSeedBytes()));
|
||||
rootKey.setCreationTimeSeconds(seed.getCreationTimeSeconds());
|
||||
initializeHierarchyUnencrypted(rootKey);
|
||||
} else {
|
||||
|
@ -524,14 +525,9 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
// data (handling encryption along the way), and letting us patch it up with the extra data we care about.
|
||||
LinkedList<Protos.Key> entries = newLinkedList();
|
||||
if (seed != null) {
|
||||
Protos.Key.Builder seedEntry = BasicKeyChain.serializeEncryptableItem(seed);
|
||||
seedEntry.setType(Protos.Key.Type.DETERMINISTIC_ROOT_SEED);
|
||||
entries.add(seedEntry.build());
|
||||
if (seed.hasMnemonicCode()) {
|
||||
Protos.Key.Builder mnemonicEntry = BasicKeyChain.serializeEncryptableItem(seed.getMnemonicEncryptableItem());
|
||||
mnemonicEntry.setType(Protos.Key.Type.DETERMINISTIC_MNEMONIC);
|
||||
entries.add(mnemonicEntry.build());
|
||||
}
|
||||
Protos.Key.Builder mnemonicEntry = BasicKeyChain.serializeEncryptableItem(seed);
|
||||
mnemonicEntry.setType(Protos.Key.Type.DETERMINISTIC_MNEMONIC);
|
||||
entries.add(mnemonicEntry.build());
|
||||
}
|
||||
Map<ECKey, Protos.Key.Builder> keys = basicKeyChain.serializeToEditableProtobufs();
|
||||
for (Map.Entry<ECKey, Protos.Key.Builder> entry : keys.entrySet()) {
|
||||
|
@ -577,18 +573,6 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
for (Protos.Key key : keys) {
|
||||
final Protos.Key.Type t = key.getType();
|
||||
if (t == Protos.Key.Type.DETERMINISTIC_MNEMONIC) {
|
||||
checkState(chain == null);
|
||||
checkState(seed != null);
|
||||
if (key.hasSecretBytes()) {
|
||||
seed.setMnemonicCode(key.getSecretBytes().toByteArray());
|
||||
} else if (key.hasEncryptedData()) {
|
||||
EncryptedData data = new EncryptedData(key.getEncryptedData().getInitialisationVector().toByteArray(),
|
||||
key.getEncryptedData().getEncryptedPrivateKey().toByteArray());
|
||||
seed.setEncryptedMnemonicCode(data);
|
||||
} else {
|
||||
throw new UnreadableWalletException("Malformed key proto: " + key.toString());
|
||||
}
|
||||
} else if (t == Protos.Key.Type.DETERMINISTIC_ROOT_SEED) {
|
||||
if (chain != null) {
|
||||
checkState(lookaheadSize >= 0);
|
||||
chain.setLookaheadSize(lookaheadSize);
|
||||
|
@ -597,8 +581,9 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
chain = null;
|
||||
}
|
||||
long timestamp = key.getCreationTimestamp() / 1000;
|
||||
String passphrase = DEFAULT_PASSPHRASE_FOR_MNEMONIC; // FIXME allow non-empty passphrase
|
||||
if (key.hasSecretBytes()) {
|
||||
seed = new DeterministicSeed(key.getSecretBytes().toByteArray(), timestamp);
|
||||
seed = new DeterministicSeed(key.getSecretBytes().toStringUtf8(), passphrase, timestamp);
|
||||
} else if (key.hasEncryptedData()) {
|
||||
EncryptedData data = new EncryptedData(key.getEncryptedData().getInitialisationVector().toByteArray(),
|
||||
key.getEncryptedData().getEncryptedPrivateKey().toByteArray());
|
||||
|
@ -607,7 +592,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
throw new UnreadableWalletException("Malformed key proto: " + key.toString());
|
||||
}
|
||||
if (log.isDebugEnabled())
|
||||
log.debug("Deserializing: DETERMINISTIC_ROOT_SEED: {}", seed);
|
||||
log.debug("Deserializing: DETERMINISTIC_MNEMONIC: {}", seed);
|
||||
} else if (t == Protos.Key.Type.DETERMINISTIC_KEY) {
|
||||
if (!key.hasDeterministicKey())
|
||||
throw new UnreadableWalletException("Deterministic key missing extra data: " + key.toString());
|
||||
|
@ -749,7 +734,8 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
|
|||
public DeterministicKeyChain toDecrypted(KeyParameter aesKey) {
|
||||
checkState(getKeyCrypter() != null, "Key chain not encrypted");
|
||||
checkState(seed.isEncrypted());
|
||||
DeterministicSeed decSeed = seed.decrypt(getKeyCrypter(), aesKey);
|
||||
String passphrase = DEFAULT_PASSPHRASE_FOR_MNEMONIC; // FIXME allow non-empty passphrase
|
||||
DeterministicSeed decSeed = seed.decrypt(getKeyCrypter(), passphrase, aesKey);
|
||||
DeterministicKeyChain chain = new DeterministicKeyChain(decSeed);
|
||||
// Now double check that the keys match to catch the case where the key is wrong but padding didn't catch it.
|
||||
if (!chain.getWatchingKey().getPubKeyPoint().equals(getWatchingKey().getPubKeyPoint()))
|
||||
|
|
|
@ -30,7 +30,6 @@ import javax.annotation.Nullable;
|
|||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.bitcoin.core.Utils.HEX;
|
||||
|
@ -49,8 +48,7 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
public static final int MAX_SEED_ENTROPY_BITS = 512;
|
||||
public static final String UTF_8 = "UTF-8";
|
||||
|
||||
@Nullable private final byte[] unencryptedSeed;
|
||||
@Nullable private final EncryptedData encryptedSeed;
|
||||
@Nullable private final byte[] seed;
|
||||
@Nullable private List<String> mnemonicCode;
|
||||
@Nullable private EncryptedData encryptedMnemonicCode;
|
||||
private final long creationTimeSeconds;
|
||||
|
@ -69,33 +67,24 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
}
|
||||
}
|
||||
|
||||
DeterministicSeed(byte[] unencryptedSeed, List<String> mnemonic, long creationTimeSeconds) {
|
||||
this.unencryptedSeed = checkNotNull(unencryptedSeed);
|
||||
this.encryptedSeed = null;
|
||||
this.mnemonicCode = mnemonic;
|
||||
DeterministicSeed(String mnemonicCode, String passphrase, long creationTimeSeconds) throws UnreadableWalletException {
|
||||
this(decodeMnemonicCode(mnemonicCode), passphrase, creationTimeSeconds);
|
||||
}
|
||||
|
||||
DeterministicSeed(byte[] seed, List<String> mnemonic, long creationTimeSeconds) {
|
||||
this.seed = checkNotNull(seed);
|
||||
this.mnemonicCode = checkNotNull(mnemonic);
|
||||
this.encryptedMnemonicCode = null;
|
||||
this.creationTimeSeconds = creationTimeSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a seed from bytes. The mnemonic phrase is unknown.
|
||||
*/
|
||||
public DeterministicSeed(byte[] unencryptedSeed, long creationTimeSeconds) {
|
||||
this(unencryptedSeed, null, creationTimeSeconds);
|
||||
}
|
||||
|
||||
DeterministicSeed(EncryptedData encryptedSeed, EncryptedData encryptedMnemonic, long creationTimeSeconds) {
|
||||
this.unencryptedSeed = null;
|
||||
DeterministicSeed(EncryptedData encryptedMnemonic, long creationTimeSeconds) {
|
||||
this.seed = null;
|
||||
this.mnemonicCode = null;
|
||||
this.encryptedSeed = checkNotNull(encryptedSeed);
|
||||
this.encryptedMnemonicCode = encryptedMnemonic;
|
||||
this.encryptedMnemonicCode = checkNotNull(encryptedMnemonic);
|
||||
this.creationTimeSeconds = creationTimeSeconds;
|
||||
}
|
||||
|
||||
DeterministicSeed(EncryptedData encryptedSeed, long creationTimeSeconds) {
|
||||
this(encryptedSeed, null, creationTimeSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a seed from a BIP 39 mnemonic code. See {@link com.google.bitcoin.crypto.MnemonicCode} for more
|
||||
* details on this scheme.
|
||||
|
@ -116,22 +105,33 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
* @param creationTimeSeconds When the seed was originally created, UNIX time.
|
||||
*/
|
||||
public DeterministicSeed(SecureRandom random, int bits, String passphrase, long creationTimeSeconds) {
|
||||
byte[] entropy = getEntropy(random, bits);
|
||||
this(getEntropy(random, bits), passphrase, creationTimeSeconds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a seed from a BIP 39 mnemonic code. See {@link com.google.bitcoin.crypto.MnemonicCode} for more
|
||||
* details on this scheme.
|
||||
* @param entropy entropy bits, length must be divisible by 32
|
||||
* @param passphrase A user supplied passphrase, or an empty string if there is no passphrase
|
||||
* @param creationTimeSeconds When the seed was originally created, UNIX time.
|
||||
*/
|
||||
public DeterministicSeed(byte[] entropy, String passphrase, long creationTimeSeconds) {
|
||||
Preconditions.checkArgument(entropy.length % 4 == 0, "entropy size in bits not divisible by 32");
|
||||
Preconditions.checkArgument(entropy.length * 8 >= DEFAULT_SEED_ENTROPY_BITS, "entropy size too small");
|
||||
|
||||
try {
|
||||
this.mnemonicCode = getCachedMnemonicCodec().toMnemonic(entropy);
|
||||
} catch (MnemonicException.MnemonicLengthException e) {
|
||||
// cannot happen
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.unencryptedSeed = getCachedMnemonicCodec().toSeed(mnemonicCode, passphrase);
|
||||
this.encryptedSeed = null;
|
||||
this.seed = getCachedMnemonicCodec().toSeed(mnemonicCode, passphrase);
|
||||
this.encryptedMnemonicCode = null;
|
||||
this.creationTimeSeconds = creationTimeSeconds;
|
||||
}
|
||||
|
||||
private static byte[] getEntropy(SecureRandom random, int bits) {
|
||||
Preconditions.checkArgument(bits >= DEFAULT_SEED_ENTROPY_BITS, "requested entropy size too small");
|
||||
Preconditions.checkArgument(bits <= MAX_SEED_ENTROPY_BITS, "requested entropy size too large");
|
||||
Preconditions.checkArgument(bits % 32 == 0, "requested entropy size not divisible by 32");
|
||||
|
||||
byte[] seed = new byte[bits / 8];
|
||||
random.nextBytes(seed);
|
||||
|
@ -140,8 +140,8 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
|
||||
@Override
|
||||
public boolean isEncrypted() {
|
||||
checkState(unencryptedSeed != null || encryptedSeed != null);
|
||||
return encryptedSeed != null;
|
||||
checkState(mnemonicCode != null || encryptedMnemonicCode != null);
|
||||
return encryptedMnemonicCode != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,8 +156,8 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
/** Returns the seed as hex or null if encrypted. */
|
||||
@Nullable
|
||||
public String toHexString() {
|
||||
if (unencryptedSeed != null)
|
||||
return HEX.encode(unencryptedSeed);
|
||||
if (seed != null)
|
||||
return HEX.encode(seed);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
@ -165,13 +165,17 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
@Nullable
|
||||
@Override
|
||||
public byte[] getSecretBytes() {
|
||||
return unencryptedSeed;
|
||||
return getMnemonicAsBytes();
|
||||
}
|
||||
|
||||
public byte[] getSeedBytes() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public EncryptedData getEncryptedData() {
|
||||
return encryptedSeed;
|
||||
return encryptedMnemonicCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -184,43 +188,11 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
return creationTimeSeconds;
|
||||
}
|
||||
|
||||
public EncryptableItem getMnemonicEncryptableItem() {
|
||||
return new EncryptableItem() {
|
||||
@Override
|
||||
public boolean isEncrypted() {
|
||||
return DeterministicSeed.this.isEncrypted();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public byte[] getSecretBytes() {
|
||||
return getMnemonicAsBytes();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public EncryptedData getEncryptedData() {
|
||||
return encryptedMnemonicCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Protos.Wallet.EncryptionType getEncryptionType() {
|
||||
return Protos.Wallet.EncryptionType.ENCRYPTED_SCRYPT_AES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCreationTimeSeconds() {
|
||||
return creationTimeSeconds;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public DeterministicSeed encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) {
|
||||
checkState(encryptedSeed == null, "Trying to encrypt seed twice");
|
||||
checkState(unencryptedSeed != null, "Seed bytes missing so cannot encrypt");
|
||||
EncryptedData seed = keyCrypter.encrypt(unencryptedSeed, aesKey);
|
||||
EncryptedData mnemonic = (mnemonicCode != null) ? keyCrypter.encrypt(getMnemonicAsBytes(), aesKey) : null;
|
||||
return new DeterministicSeed(seed, mnemonic, creationTimeSeconds);
|
||||
checkState(encryptedMnemonicCode == null, "Trying to encrypt seed twice");
|
||||
checkState(mnemonicCode != null, "Mnemonic missing so cannot encrypt");
|
||||
EncryptedData mnemonic = keyCrypter.encrypt(getMnemonicAsBytes(), aesKey);
|
||||
return new DeterministicSeed(mnemonic, creationTimeSeconds);
|
||||
}
|
||||
|
||||
private byte[] getMnemonicAsBytes() {
|
||||
|
@ -231,19 +203,17 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
}
|
||||
}
|
||||
|
||||
public DeterministicSeed decrypt(KeyCrypter crypter, KeyParameter aesKey) {
|
||||
public DeterministicSeed decrypt(KeyCrypter crypter, String passphrase, KeyParameter aesKey) {
|
||||
checkState(isEncrypted());
|
||||
checkNotNull(encryptedSeed);
|
||||
byte[] seed = crypter.decrypt(encryptedSeed, aesKey);
|
||||
checkNotNull(encryptedMnemonicCode);
|
||||
List<String> mnemonic = null;
|
||||
try {
|
||||
if (encryptedMnemonicCode != null)
|
||||
mnemonic = decodeMnemonicCode(crypter.decrypt(encryptedMnemonicCode, aesKey));
|
||||
mnemonic = decodeMnemonicCode(crypter.decrypt(encryptedMnemonicCode, aesKey));
|
||||
} catch (UnreadableWalletException e) {
|
||||
// TODO what is the best way to handle this exception?
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new DeterministicSeed(seed, mnemonic, creationTimeSeconds);
|
||||
return new DeterministicSeed(mnemonic, passphrase, creationTimeSeconds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -254,11 +224,11 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
DeterministicSeed seed = (DeterministicSeed) o;
|
||||
|
||||
if (creationTimeSeconds != seed.creationTimeSeconds) return false;
|
||||
if (encryptedSeed != null) {
|
||||
if (seed.encryptedSeed == null) return false;
|
||||
if (!encryptedSeed.equals(seed.encryptedSeed)) return false;
|
||||
if (encryptedMnemonicCode != null) {
|
||||
if (seed.encryptedMnemonicCode == null) return false;
|
||||
if (!encryptedMnemonicCode.equals(seed.encryptedMnemonicCode)) return false;
|
||||
} else {
|
||||
if (!Arrays.equals(unencryptedSeed, seed.unencryptedSeed)) return false;
|
||||
if (!mnemonicCode.equals(seed.mnemonicCode)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -266,7 +236,7 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = encryptedSeed != null ? encryptedSeed.hashCode() : Arrays.hashCode(unencryptedSeed);
|
||||
int result = encryptedMnemonicCode != null ? encryptedMnemonicCode.hashCode() : mnemonicCode.hashCode();
|
||||
result = 31 * result + (int) (creationTimeSeconds ^ (creationTimeSeconds >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
@ -282,28 +252,17 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
getCachedMnemonicCodec().check(mnemonicCode);
|
||||
}
|
||||
|
||||
byte[] getEntropyBytes() throws MnemonicException {
|
||||
return getCachedMnemonicCodec().toEntropy(mnemonicCode);
|
||||
}
|
||||
|
||||
/** Get the mnemonic code, or null if unknown. */
|
||||
@Nullable
|
||||
public List<String> getMnemonicCode() {
|
||||
return mnemonicCode;
|
||||
}
|
||||
|
||||
/** Set encrypted mnemonic code. Used by protobuf deserializer. */
|
||||
public void setEncryptedMnemonicCode(EncryptedData encryptedMnemonicCode) {
|
||||
this.encryptedMnemonicCode = encryptedMnemonicCode;
|
||||
}
|
||||
|
||||
/** Set mnemonic code from UTF-8 encoded bytes. */
|
||||
public void setMnemonicCode(@Nullable byte[] mnemonicCode) throws UnreadableWalletException {
|
||||
this.mnemonicCode = decodeMnemonicCode(mnemonicCode);
|
||||
}
|
||||
|
||||
/** Whether the mnemonic code is known for this seed. */
|
||||
public boolean hasMnemonicCode() {
|
||||
return mnemonicCode != null || encryptedMnemonicCode != null;
|
||||
}
|
||||
|
||||
private List<String> decodeMnemonicCode(byte[] mnemonicCode) throws UnreadableWalletException {
|
||||
private static List<String> decodeMnemonicCode(byte[] mnemonicCode) throws UnreadableWalletException {
|
||||
String code = null;
|
||||
try {
|
||||
code = new String(mnemonicCode, "UTF-8");
|
||||
|
@ -312,4 +271,8 @@ public class DeterministicSeed implements EncryptableItem {
|
|||
}
|
||||
return Splitter.on(" ").splitToList(code);
|
||||
}
|
||||
|
||||
private static List<String> decodeMnemonicCode(String mnemonicCode) {
|
||||
return Splitter.on(" ").splitToList(mnemonicCode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -731,15 +731,16 @@ public class KeyChainGroup {
|
|||
}
|
||||
|
||||
log.info("Auto-upgrading pre-HD wallet using oldest non-rotating private key");
|
||||
byte[] seed = checkNotNull(keyToUse.getSecretBytes());
|
||||
byte[] entropy = checkNotNull(keyToUse.getSecretBytes());
|
||||
// Private keys should be at least 128 bits long.
|
||||
checkState(seed.length >= DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8);
|
||||
checkState(entropy.length >= DeterministicSeed.DEFAULT_SEED_ENTROPY_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, DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8); // final argument is exclusive range.
|
||||
checkState(seed.length == DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8);
|
||||
DeterministicKeyChain chain = new DeterministicKeyChain(seed, keyToUse.getCreationTimeSeconds());
|
||||
entropy = Arrays.copyOfRange(entropy, 0, DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8); // final argument is exclusive range.
|
||||
checkState(entropy.length == DeterministicSeed.DEFAULT_SEED_ENTROPY_BITS / 8);
|
||||
String passphrase = ""; // FIXME allow non-empty passphrase
|
||||
DeterministicKeyChain chain = new DeterministicKeyChain(entropy, passphrase, keyToUse.getCreationTimeSeconds());
|
||||
if (aesKey != null) {
|
||||
chain = chain.toEncrypted(checkNotNull(basic.getKeyCrypter()), aesKey);
|
||||
}
|
||||
|
|
|
@ -2526,15 +2526,15 @@ public final class Protos {
|
|||
*/
|
||||
ENCRYPTED_SCRYPT_AES(1, 2),
|
||||
/**
|
||||
* <code>DETERMINISTIC_ROOT_SEED = 3;</code>
|
||||
* <code>DETERMINISTIC_MNEMONIC = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
**
|
||||
* Not really a key, but rather contains the seed for a deterministic key hierarchy in the private_key field.
|
||||
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
* </pre>
|
||||
*/
|
||||
DETERMINISTIC_ROOT_SEED(2, 3),
|
||||
DETERMINISTIC_MNEMONIC(2, 3),
|
||||
/**
|
||||
* <code>DETERMINISTIC_KEY = 4;</code>
|
||||
*
|
||||
|
@ -2548,17 +2548,6 @@ public final class Protos {
|
|||
* </pre>
|
||||
*/
|
||||
DETERMINISTIC_KEY(3, 4),
|
||||
/**
|
||||
* <code>DETERMINISTIC_MNEMONIC = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
**
|
||||
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
* Must be immediately after DETERMINISTIC_KEY
|
||||
* </pre>
|
||||
*/
|
||||
DETERMINISTIC_MNEMONIC(4, 5),
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -2578,15 +2567,15 @@ public final class Protos {
|
|||
*/
|
||||
public static final int ENCRYPTED_SCRYPT_AES_VALUE = 2;
|
||||
/**
|
||||
* <code>DETERMINISTIC_ROOT_SEED = 3;</code>
|
||||
* <code>DETERMINISTIC_MNEMONIC = 3;</code>
|
||||
*
|
||||
* <pre>
|
||||
**
|
||||
* Not really a key, but rather contains the seed for a deterministic key hierarchy in the private_key field.
|
||||
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
* </pre>
|
||||
*/
|
||||
public static final int DETERMINISTIC_ROOT_SEED_VALUE = 3;
|
||||
public static final int DETERMINISTIC_MNEMONIC_VALUE = 3;
|
||||
/**
|
||||
* <code>DETERMINISTIC_KEY = 4;</code>
|
||||
*
|
||||
|
@ -2600,17 +2589,6 @@ public final class Protos {
|
|||
* </pre>
|
||||
*/
|
||||
public static final int DETERMINISTIC_KEY_VALUE = 4;
|
||||
/**
|
||||
* <code>DETERMINISTIC_MNEMONIC = 5;</code>
|
||||
*
|
||||
* <pre>
|
||||
**
|
||||
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
* Must be immediately after DETERMINISTIC_KEY
|
||||
* </pre>
|
||||
*/
|
||||
public static final int DETERMINISTIC_MNEMONIC_VALUE = 5;
|
||||
|
||||
|
||||
public final int getNumber() { return value; }
|
||||
|
@ -2619,9 +2597,8 @@ public final class Protos {
|
|||
switch (value) {
|
||||
case 1: return ORIGINAL;
|
||||
case 2: return ENCRYPTED_SCRYPT_AES;
|
||||
case 3: return DETERMINISTIC_ROOT_SEED;
|
||||
case 3: return DETERMINISTIC_MNEMONIC;
|
||||
case 4: return DETERMINISTIC_KEY;
|
||||
case 5: return DETERMINISTIC_MNEMONIC;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
@ -16184,67 +16161,66 @@ public final class Protos {
|
|||
"ey\030\002 \002(\014\"y\n\020DeterministicKey\022\022\n\nchain_co" +
|
||||
"de\030\001 \002(\014\022\014\n\004path\030\002 \003(\r\022\026\n\016issued_subkeys" +
|
||||
"\030\003 \001(\r\022\026\n\016lookahead_size\030\004 \001(\r\022\023\n\013isFoll" +
|
||||
"owing\030\005 \001(\010\"\336\002\n\003Key\022\036\n\004type\030\001 \002(\0162\020.wall" +
|
||||
"owing\030\005 \001(\010\"\301\002\n\003Key\022\036\n\004type\030\001 \002(\0162\020.wall" +
|
||||
"et.Key.Type\022\024\n\014secret_bytes\030\002 \001(\014\022-\n\016enc" +
|
||||
"rypted_data\030\006 \001(\0132\025.wallet.EncryptedData",
|
||||
"\022\022\n\npublic_key\030\003 \001(\014\022\r\n\005label\030\004 \001(\t\022\032\n\022c" +
|
||||
"reation_timestamp\030\005 \001(\003\0223\n\021deterministic" +
|
||||
"_key\030\007 \001(\0132\030.wallet.DeterministicKey\"~\n\004" +
|
||||
"_key\030\007 \001(\0132\030.wallet.DeterministicKey\"a\n\004" +
|
||||
"Type\022\014\n\010ORIGINAL\020\001\022\030\n\024ENCRYPTED_SCRYPT_A" +
|
||||
"ES\020\002\022\033\n\027DETERMINISTIC_ROOT_SEED\020\003\022\025\n\021DET" +
|
||||
"ERMINISTIC_KEY\020\004\022\032\n\026DETERMINISTIC_MNEMON" +
|
||||
"IC\020\005\"5\n\006Script\022\017\n\007program\030\001 \002(\014\022\032\n\022creat" +
|
||||
"ion_timestamp\030\002 \002(\003\"\222\001\n\020TransactionInput" +
|
||||
"\022\"\n\032transaction_out_point_hash\030\001 \002(\014\022#\n\033" +
|
||||
"transaction_out_point_index\030\002 \002(\r\022\024\n\014scr",
|
||||
"ipt_bytes\030\003 \002(\014\022\020\n\010sequence\030\004 \001(\r\022\r\n\005val" +
|
||||
"ue\030\005 \001(\003\"\177\n\021TransactionOutput\022\r\n\005value\030\001" +
|
||||
" \002(\003\022\024\n\014script_bytes\030\002 \002(\014\022!\n\031spent_by_t" +
|
||||
"ransaction_hash\030\003 \001(\014\022\"\n\032spent_by_transa" +
|
||||
"ction_index\030\004 \001(\005\"\234\003\n\025TransactionConfide" +
|
||||
"nce\0220\n\004type\030\001 \001(\0162\".wallet.TransactionCo" +
|
||||
"nfidence.Type\022\032\n\022appeared_at_height\030\002 \001(" +
|
||||
"\005\022\036\n\026overriding_transaction\030\003 \001(\014\022\r\n\005dep" +
|
||||
"th\030\004 \001(\005\022\021\n\twork_done\030\005 \001(\003\022)\n\014broadcast" +
|
||||
"_by\030\006 \003(\0132\023.wallet.PeerAddress\0224\n\006source",
|
||||
"\030\007 \001(\0162$.wallet.TransactionConfidence.So" +
|
||||
"urce\"O\n\004Type\022\013\n\007UNKNOWN\020\000\022\014\n\010BUILDING\020\001\022" +
|
||||
"\013\n\007PENDING\020\002\022\025\n\021NOT_IN_BEST_CHAIN\020\003\022\010\n\004D" +
|
||||
"EAD\020\004\"A\n\006Source\022\022\n\016SOURCE_UNKNOWN\020\000\022\022\n\016S" +
|
||||
"OURCE_NETWORK\020\001\022\017\n\013SOURCE_SELF\020\002\"\236\004\n\013Tra" +
|
||||
"nsaction\022\017\n\007version\030\001 \002(\005\022\014\n\004hash\030\002 \002(\014\022" +
|
||||
"&\n\004pool\030\003 \001(\0162\030.wallet.Transaction.Pool\022" +
|
||||
"\021\n\tlock_time\030\004 \001(\r\022\022\n\nupdated_at\030\005 \001(\003\0223" +
|
||||
"\n\021transaction_input\030\006 \003(\0132\030.wallet.Trans" +
|
||||
"actionInput\0225\n\022transaction_output\030\007 \003(\0132",
|
||||
"\031.wallet.TransactionOutput\022\022\n\nblock_hash" +
|
||||
"\030\010 \003(\014\022 \n\030block_relativity_offsets\030\013 \003(\005" +
|
||||
"\0221\n\nconfidence\030\t \001(\0132\035.wallet.Transactio" +
|
||||
"nConfidence\0225\n\007purpose\030\n \001(\0162\033.wallet.Tr" +
|
||||
"ansaction.Purpose:\007UNKNOWN\"Y\n\004Pool\022\013\n\007UN" +
|
||||
"SPENT\020\004\022\t\n\005SPENT\020\005\022\014\n\010INACTIVE\020\002\022\010\n\004DEAD" +
|
||||
"\020\n\022\013\n\007PENDING\020\020\022\024\n\020PENDING_INACTIVE\020\022\":\n" +
|
||||
"\007Purpose\022\013\n\007UNKNOWN\020\000\022\020\n\014USER_PAYMENT\020\001\022" +
|
||||
"\020\n\014KEY_ROTATION\020\002\"N\n\020ScryptParameters\022\014\n" +
|
||||
"\004salt\030\001 \002(\014\022\020\n\001n\030\002 \001(\003:\00516384\022\014\n\001r\030\003 \001(\005",
|
||||
":\0018\022\014\n\001p\030\004 \001(\005:\0011\"8\n\tExtension\022\n\n\002id\030\001 \002" +
|
||||
"(\t\022\014\n\004data\030\002 \002(\014\022\021\n\tmandatory\030\003 \002(\010\" \n\003T" +
|
||||
"ag\022\013\n\003tag\030\001 \002(\t\022\014\n\004data\030\002 \002(\014\"\261\004\n\006Wallet" +
|
||||
"\022\032\n\022network_identifier\030\001 \002(\t\022\034\n\024last_see" +
|
||||
"n_block_hash\030\002 \001(\014\022\036\n\026last_seen_block_he" +
|
||||
"ight\030\014 \001(\r\022!\n\031last_seen_block_time_secs\030" +
|
||||
"\016 \001(\003\022\030\n\003key\030\003 \003(\0132\013.wallet.Key\022(\n\013trans" +
|
||||
"action\030\004 \003(\0132\023.wallet.Transaction\022&\n\016wat" +
|
||||
"ched_script\030\017 \003(\0132\016.wallet.Script\022C\n\017enc" +
|
||||
"ryption_type\030\005 \001(\0162\035.wallet.Wallet.Encry",
|
||||
"ptionType:\013UNENCRYPTED\0227\n\025encryption_par" +
|
||||
"ameters\030\006 \001(\0132\030.wallet.ScryptParameters\022" +
|
||||
"\022\n\007version\030\007 \001(\005:\0011\022$\n\textension\030\n \003(\0132\021" +
|
||||
".wallet.Extension\022\023\n\013description\030\013 \001(\t\022\031" +
|
||||
"\n\021key_rotation_time\030\r \001(\004\022\031\n\004tags\030\020 \003(\0132" +
|
||||
"\013.wallet.Tag\";\n\016EncryptionType\022\017\n\013UNENCR" +
|
||||
"YPTED\020\001\022\030\n\024ENCRYPTED_SCRYPT_AES\020\002B\035\n\023org" +
|
||||
".bitcoinj.walletB\006Protos"
|
||||
"ES\020\002\022\032\n\026DETERMINISTIC_MNEMONIC\020\003\022\025\n\021DETE" +
|
||||
"RMINISTIC_KEY\020\004\"5\n\006Script\022\017\n\007program\030\001 \002" +
|
||||
"(\014\022\032\n\022creation_timestamp\030\002 \002(\003\"\222\001\n\020Trans" +
|
||||
"actionInput\022\"\n\032transaction_out_point_has" +
|
||||
"h\030\001 \002(\014\022#\n\033transaction_out_point_index\030\002" +
|
||||
" \002(\r\022\024\n\014script_bytes\030\003 \002(\014\022\020\n\010sequence\030\004",
|
||||
" \001(\r\022\r\n\005value\030\005 \001(\003\"\177\n\021TransactionOutput" +
|
||||
"\022\r\n\005value\030\001 \002(\003\022\024\n\014script_bytes\030\002 \002(\014\022!\n" +
|
||||
"\031spent_by_transaction_hash\030\003 \001(\014\022\"\n\032spen" +
|
||||
"t_by_transaction_index\030\004 \001(\005\"\234\003\n\025Transac" +
|
||||
"tionConfidence\0220\n\004type\030\001 \001(\0162\".wallet.Tr" +
|
||||
"ansactionConfidence.Type\022\032\n\022appeared_at_" +
|
||||
"height\030\002 \001(\005\022\036\n\026overriding_transaction\030\003" +
|
||||
" \001(\014\022\r\n\005depth\030\004 \001(\005\022\021\n\twork_done\030\005 \001(\003\022)" +
|
||||
"\n\014broadcast_by\030\006 \003(\0132\023.wallet.PeerAddres" +
|
||||
"s\0224\n\006source\030\007 \001(\0162$.wallet.TransactionCo",
|
||||
"nfidence.Source\"O\n\004Type\022\013\n\007UNKNOWN\020\000\022\014\n\010" +
|
||||
"BUILDING\020\001\022\013\n\007PENDING\020\002\022\025\n\021NOT_IN_BEST_C" +
|
||||
"HAIN\020\003\022\010\n\004DEAD\020\004\"A\n\006Source\022\022\n\016SOURCE_UNK" +
|
||||
"NOWN\020\000\022\022\n\016SOURCE_NETWORK\020\001\022\017\n\013SOURCE_SEL" +
|
||||
"F\020\002\"\236\004\n\013Transaction\022\017\n\007version\030\001 \002(\005\022\014\n\004" +
|
||||
"hash\030\002 \002(\014\022&\n\004pool\030\003 \001(\0162\030.wallet.Transa" +
|
||||
"ction.Pool\022\021\n\tlock_time\030\004 \001(\r\022\022\n\nupdated" +
|
||||
"_at\030\005 \001(\003\0223\n\021transaction_input\030\006 \003(\0132\030.w" +
|
||||
"allet.TransactionInput\0225\n\022transaction_ou" +
|
||||
"tput\030\007 \003(\0132\031.wallet.TransactionOutput\022\022\n",
|
||||
"\nblock_hash\030\010 \003(\014\022 \n\030block_relativity_of" +
|
||||
"fsets\030\013 \003(\005\0221\n\nconfidence\030\t \001(\0132\035.wallet" +
|
||||
".TransactionConfidence\0225\n\007purpose\030\n \001(\0162" +
|
||||
"\033.wallet.Transaction.Purpose:\007UNKNOWN\"Y\n" +
|
||||
"\004Pool\022\013\n\007UNSPENT\020\004\022\t\n\005SPENT\020\005\022\014\n\010INACTIV" +
|
||||
"E\020\002\022\010\n\004DEAD\020\n\022\013\n\007PENDING\020\020\022\024\n\020PENDING_IN" +
|
||||
"ACTIVE\020\022\":\n\007Purpose\022\013\n\007UNKNOWN\020\000\022\020\n\014USER" +
|
||||
"_PAYMENT\020\001\022\020\n\014KEY_ROTATION\020\002\"N\n\020ScryptPa" +
|
||||
"rameters\022\014\n\004salt\030\001 \002(\014\022\020\n\001n\030\002 \001(\003:\00516384" +
|
||||
"\022\014\n\001r\030\003 \001(\005:\0018\022\014\n\001p\030\004 \001(\005:\0011\"8\n\tExtensio",
|
||||
"n\022\n\n\002id\030\001 \002(\t\022\014\n\004data\030\002 \002(\014\022\021\n\tmandatory" +
|
||||
"\030\003 \002(\010\" \n\003Tag\022\013\n\003tag\030\001 \002(\t\022\014\n\004data\030\002 \002(\014" +
|
||||
"\"\261\004\n\006Wallet\022\032\n\022network_identifier\030\001 \002(\t\022" +
|
||||
"\034\n\024last_seen_block_hash\030\002 \001(\014\022\036\n\026last_se" +
|
||||
"en_block_height\030\014 \001(\r\022!\n\031last_seen_block" +
|
||||
"_time_secs\030\016 \001(\003\022\030\n\003key\030\003 \003(\0132\013.wallet.K" +
|
||||
"ey\022(\n\013transaction\030\004 \003(\0132\023.wallet.Transac" +
|
||||
"tion\022&\n\016watched_script\030\017 \003(\0132\016.wallet.Sc" +
|
||||
"ript\022C\n\017encryption_type\030\005 \001(\0162\035.wallet.W" +
|
||||
"allet.EncryptionType:\013UNENCRYPTED\0227\n\025enc",
|
||||
"ryption_parameters\030\006 \001(\0132\030.wallet.Scrypt" +
|
||||
"Parameters\022\022\n\007version\030\007 \001(\005:\0011\022$\n\textens" +
|
||||
"ion\030\n \003(\0132\021.wallet.Extension\022\023\n\013descript" +
|
||||
"ion\030\013 \001(\t\022\031\n\021key_rotation_time\030\r \001(\004\022\031\n\004" +
|
||||
"tags\030\020 \003(\0132\013.wallet.Tag\";\n\016EncryptionTyp" +
|
||||
"e\022\017\n\013UNENCRYPTED\020\001\022\030\n\024ENCRYPTED_SCRYPT_A" +
|
||||
"ES\020\002B\035\n\023org.bitcoinj.walletB\006Protos"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
|
|
|
@ -24,7 +24,6 @@ import com.google.bitcoin.store.UnreadableWalletException;
|
|||
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
import com.google.bitcoin.utils.Threading;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.io.Resources;
|
||||
import org.bitcoinj.wallet.Protos;
|
||||
|
@ -41,7 +40,7 @@ import static org.junit.Assert.*;
|
|||
|
||||
public class DeterministicKeyChainTest {
|
||||
private DeterministicKeyChain chain;
|
||||
private final byte[] SEED = Sha256Hash.create("don't use a string seed like this in real life".getBytes()).getBytes();
|
||||
private final byte[] ENTROPY = Sha256Hash.create("don't use a string seed like this in real life".getBytes()).getBytes();
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
@ -49,7 +48,7 @@ public class DeterministicKeyChainTest {
|
|||
// You should use a random seed instead. The secs constant comes from the unit test file, so we can compare
|
||||
// serialized data properly.
|
||||
long secs = 1389353062L;
|
||||
chain = new DeterministicKeyChain(SEED, secs);
|
||||
chain = new DeterministicKeyChain(ENTROPY, "", secs);
|
||||
chain.setLookaheadSize(10);
|
||||
assertEquals(secs, checkNotNull(chain.getSeed()).getCreationTimeSeconds());
|
||||
}
|
||||
|
@ -59,16 +58,16 @@ public class DeterministicKeyChainTest {
|
|||
ECKey key1 = chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
|
||||
ECKey key2 = chain.getKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
|
||||
|
||||
final Address address = new Address(UnitTestParams.get(), "n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa");
|
||||
final Address address = new Address(UnitTestParams.get(), "n1bQNoEx8uhmCzzA5JPG6sFdtsUQhwiQJV");
|
||||
assertEquals(address, key1.toAddress(UnitTestParams.get()));
|
||||
assertEquals("n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X", key2.toAddress(UnitTestParams.get()).toString());
|
||||
assertEquals("mnHUcqUVvrfi5kAaXJDQzBb9HsWs78b42R", key2.toAddress(UnitTestParams.get()).toString());
|
||||
assertEquals(key1, chain.findKeyFromPubHash(address.getHash160()));
|
||||
assertEquals(key2, chain.findKeyFromPubKey(key2.getPubKey()));
|
||||
|
||||
key1.sign(Sha256Hash.ZERO_HASH);
|
||||
|
||||
ECKey key3 = chain.getKey(KeyChain.KeyPurpose.CHANGE);
|
||||
assertEquals("mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn", key3.toAddress(UnitTestParams.get()).toString());
|
||||
assertEquals("mqumHgVDqNzuXNrszBmi7A2UpmwaPMx4HQ", key3.toAddress(UnitTestParams.get()).toString());
|
||||
key3.sign(Sha256Hash.ZERO_HASH);
|
||||
}
|
||||
|
||||
|
@ -77,7 +76,7 @@ public class DeterministicKeyChainTest {
|
|||
// Check that we get the right events at the right time.
|
||||
final List<List<ECKey>> listenerKeys = Lists.newArrayList();
|
||||
long secs = 1389353062L;
|
||||
chain = new DeterministicKeyChain(SEED, secs);
|
||||
chain = new DeterministicKeyChain(ENTROPY, "", secs);
|
||||
chain.addEventListener(new AbstractKeyChainEventListener() {
|
||||
@Override
|
||||
public void onKeysAdded(List<ECKey> keys) {
|
||||
|
@ -219,7 +218,7 @@ public class DeterministicKeyChainTest {
|
|||
|
||||
DeterministicKey watchingKey = chain.getWatchingKey();
|
||||
final String pub58 = watchingKey.serializePubB58();
|
||||
assertEquals("xpub68KFnj3bqUx1s7mHejLDBPywCAKdJEu1b49uniEEn2WSbHmZ7xbLqFTjJbtx1LUcAt1DwhoqWHmo2s5WMJp6wi38CiF2hYD49qVViKVvAoi", pub58);
|
||||
assertEquals("xpub69KR9epSNBM59KLuasxMU5CyKytMJjBP5HEZ5p8YoGUCpM6cM9hqxB9DDPCpUUtqmw5duTckvPfwpoWGQUFPmRLpxs5jYiTf2u6xRMcdhDf", pub58);
|
||||
watchingKey = DeterministicKey.deserializeB58(null, pub58);
|
||||
watchingKey.setCreationTimeSeconds(100000);
|
||||
chain = DeterministicKeyChain.watch(watchingKey);
|
||||
|
|
|
@ -56,8 +56,8 @@ public class KeyChainGroupTest {
|
|||
}
|
||||
|
||||
private KeyChainGroup createMarriedKeyChainGroup() {
|
||||
byte[] seedBytes = Sha256Hash.create("don't use a seed like this in real life".getBytes()).getBytes();
|
||||
DeterministicSeed seed = new DeterministicSeed(seedBytes, MnemonicCode.BIP39_STANDARDISATION_TIME_SECS);
|
||||
byte[] entropy = Sha256Hash.create("don't use a seed like this in real life".getBytes()).getBytes();
|
||||
DeterministicSeed seed = new DeterministicSeed(entropy, "", MnemonicCode.BIP39_STANDARDISATION_TIME_SECS);
|
||||
KeyChainGroup group = new KeyChainGroup(params, seed, ImmutableList.of(watchingAccountKey));
|
||||
group.setLookaheadSize(LOOKAHEAD_SIZE);
|
||||
group.getActiveKeyChain();
|
||||
|
@ -380,25 +380,25 @@ public class KeyChainGroupTest {
|
|||
|
||||
@Test
|
||||
public void serialization() throws Exception {
|
||||
assertEquals(INITIAL_KEYS + 2 /* for the seed */, group.serializeToProtobuf().size());
|
||||
assertEquals(INITIAL_KEYS + 1 /* for the seed */, group.serializeToProtobuf().size());
|
||||
group = KeyChainGroup.fromProtobufUnencrypted(params, group.serializeToProtobuf());
|
||||
group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
|
||||
DeterministicKey key1 = group.freshKey(KeyChain.KeyPurpose.RECEIVE_FUNDS);
|
||||
DeterministicKey key2 = group.freshKey(KeyChain.KeyPurpose.CHANGE);
|
||||
List<Protos.Key> protoKeys1 = group.serializeToProtobuf();
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 2 /* for the seed */ + 1, protoKeys1.size());
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 1, protoKeys1.size());
|
||||
group.importKeys(new ECKey());
|
||||
List<Protos.Key> protoKeys2 = group.serializeToProtobuf();
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 2 /* for the seed */ + 2, protoKeys2.size());
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 2, protoKeys2.size());
|
||||
|
||||
group = KeyChainGroup.fromProtobufUnencrypted(params, protoKeys1);
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 2 /* for the seed */ + 1, protoKeys1.size());
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 1, protoKeys1.size());
|
||||
assertTrue(group.hasKey(key1));
|
||||
assertTrue(group.hasKey(key2));
|
||||
assertEquals(key2, group.currentKey(KeyChain.KeyPurpose.CHANGE));
|
||||
assertEquals(key1, group.currentKey(KeyChain.KeyPurpose.RECEIVE_FUNDS));
|
||||
group = KeyChainGroup.fromProtobufUnencrypted(params, protoKeys2);
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 2 /* for the seed */ + 2, protoKeys2.size());
|
||||
assertEquals(INITIAL_KEYS + ((LOOKAHEAD_SIZE + 1) * 2) + 1 /* for the seed */ + 2, protoKeys2.size());
|
||||
assertTrue(group.hasKey(key1));
|
||||
assertTrue(group.hasKey(key2));
|
||||
|
||||
|
@ -505,7 +505,7 @@ public class KeyChainGroupTest {
|
|||
|
||||
// Check we used the right (oldest) key despite backwards import order.
|
||||
byte[] truncatedBytes = Arrays.copyOfRange(key1.getSecretBytes(), 0, 16);
|
||||
assertArrayEquals(seed1.getSecretBytes(), truncatedBytes);
|
||||
assertArrayEquals(seed1.getEntropyBytes(), truncatedBytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -524,7 +524,7 @@ public class KeyChainGroupTest {
|
|||
assertNotNull(seed);
|
||||
// Check we used the right key: oldest non rotating.
|
||||
byte[] truncatedBytes = Arrays.copyOfRange(key2.getSecretBytes(), 0, 16);
|
||||
assertArrayEquals(seed.getSecretBytes(), truncatedBytes);
|
||||
assertArrayEquals(seed.getEntropyBytes(), truncatedBytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -548,9 +548,9 @@ public class KeyChainGroupTest {
|
|||
final DeterministicSeed deterministicSeed = group.getActiveKeyChain().getSeed();
|
||||
assertNotNull(deterministicSeed);
|
||||
assertTrue(deterministicSeed.isEncrypted());
|
||||
byte[] seed = checkNotNull(group.getActiveKeyChain().toDecrypted(aesKey).getSeed()).getSecretBytes();
|
||||
byte[] entropy = checkNotNull(group.getActiveKeyChain().toDecrypted(aesKey).getSeed()).getEntropyBytes();
|
||||
// Check we used the right key: oldest non rotating.
|
||||
byte[] truncatedBytes = Arrays.copyOfRange(key.getSecretBytes(), 0, 16);
|
||||
assertArrayEquals(seed, truncatedBytes);
|
||||
assertArrayEquals(entropy, truncatedBytes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
type: DETERMINISTIC_ROOT_SEED
|
||||
secret_bytes: "\004<r\377aT\'\356M\257w\260R\006\253\322}\343\267eW6S\233\210\352NS;\275I-"
|
||||
type: DETERMINISTIC_MNEMONIC
|
||||
secret_bytes: "aerobic toe save section draw warm cute upon raccoon mother priority pilot taste sweet next traffic fatal sword dentist original crisp team caution rebel"
|
||||
creation_timestamp: 1389353062000
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
secret_bytes: "\241\346\003RF\t\027\367\a\f\333^C&\302-\335\314\353t&h\335{ \032\364\267\335\235\345\276"
|
||||
public_key: "\003\361\245l\225\304\247X]\256,_hn\362\031\243\220\220\237z0\\<\022-O\ts\244\250\344A"
|
||||
secret_bytes: "\270E0\202(\362b\023\276\264\347\226E2\360\221\347\325\233L\203\3276\272\213\2436&\304\373\221\025"
|
||||
public_key: "\002\342$\253\332\031\352\324q\316M\251}\274\267\370X$\366>Q\316\005\330\376\353f!WHLL\a"
|
||||
creation_timestamp: 1389353062000
|
||||
deterministic_key {
|
||||
chain_code: ",\263\335\024\031\221c;~\325\326\272\367*\r+\032H\270\026\234\226\357\222i_VxP\200x\252"
|
||||
chain_code: "XL\240FW\203\316\230\334\374J\003\357=\215\001\206\365\207Z\006m\334X`\236,;_\304\000^"
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
secret_bytes: "\364\r-u\037\337Sl\272\314\221L\306\356?\3505d\330\321_3W\234R#\035\273z\341x\275"
|
||||
public_key: "\002LOV+\260\017\024lxz\021\236Xv\000X\324e\244\037\243\325\325f\003vs*]\260\340\035"
|
||||
secret_bytes: "\354B\331\275;\000\254?\3428\006\220G\365\243\333s\260s\213R\313\307\377f\331B\351\327=\001\333"
|
||||
public_key: "\002\357\\\252\376]\023\315\'\316`\317\362\032@\232\"\360\331\335\221] `\016,\351<\b\300\225\032m"
|
||||
deterministic_key {
|
||||
chain_code: "\377\340\2459\230\210\367\361\362\205\267\244#\t#\360\215\221_\302v\315{\200Y\210\224\"\243\272\256\301"
|
||||
chain_code: "\370\017\223\021O?.@gZ|\233j\3437\317q-\241!J \323\'\264s\203\314\321\v\346"
|
||||
path: 2147483648
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
secret_bytes: "~\301G\035\221\b\024\023\275\211s\273\270\205/4\233ai\366~\006\341$lc\000\272\336\021\347\305"
|
||||
public_key: "\002\264\r,\017e\213\016W\372\024W\215z\022C@+A\2720G\016\034\353\202\312\372\251\206\035r"
|
||||
secret_bytes: "<M\020I\364\276\336Z\255\341\330\257\337 \366E_\027\2433w\325\263\"$\350\f\244\006\251u\021"
|
||||
public_key: "\002\361V\216\001\371p\270\212\272\236%\216\356o\025g\r\035>a\305j\001P\217Q\242\261.\353\367\315"
|
||||
deterministic_key {
|
||||
chain_code: "\000Mm\373e\255\363\373\'\265A\003\247\320U\305\340\342\233\033\034\312zTR\006\347Yu\362b\366"
|
||||
chain_code: "\231B\211S[\216\237\277q{a\365\216\325\250\223s\v\n(\364\257@3c\312rix\260c\217"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
issued_subkeys: 2
|
||||
|
@ -30,10 +30,10 @@ deterministic_key {
|
|||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
secret_bytes: "\"\273\024]\271iR\237\335\343HN\353\352\v\220\241\006\022\302\244W\033~\260HTtz\005\376F"
|
||||
public_key: "\002\330b\034\023\320\217|!\271p\034\017p\330!\245\233j\376\b\316\373\231D\324\271d\217h\217\016^"
|
||||
secret_bytes: "\f0\266\235\272\205\212:\265\372\214P\226\344\a{S0\354\250\210\316L\256;W\036\200t\347\343\246"
|
||||
public_key: "\0022\n\252\267NDr.7i7\332\232x\367\204G-|\204\301\333G\033g\300O\241\006\217\366\370"
|
||||
deterministic_key {
|
||||
chain_code: "\367j\245\025U\265\346\v\234\275\343\rd\214q\004\232\253\312\222Hi\305\201\370`^\304\210\034p*"
|
||||
chain_code: "\213\237\327\245a\273\274\310\377\360\351\352<\211k\033g\0251>y\236\345Jb\244[\b\fO\0311"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
issued_subkeys: 1
|
||||
|
@ -41,207 +41,207 @@ deterministic_key {
|
|||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\306\337\017!F\303;\257Z\320:w\353\304\021L#\250\255\345X\023k\233\323\273\253\331s\352\362\024"
|
||||
public_key: "\002O_Q\223\337\360\245\234\322b_op\b?\030\364\255l\206\344`w\274\204\"\257\235U<}\377"
|
||||
deterministic_key {
|
||||
chain_code: "RS\20672^\r\265\fNCd\305\235\266\a\232\033\303\316\230\376FK\322\314\300}\335zk\016"
|
||||
chain_code: "\331\233\342\227\336r\212>\021\022p\347* +\220\021{\206\310Z\314\335\322\230\331\365\221}\321\036\035"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 0
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\341#\025-h\212\273XE\211\266\224|\222\251\335\375?\275A\350rU\341\212\361\221\267\303\313I\t"
|
||||
public_key: "\003\270\311\006\363\375\002{\310\254n\301\366\303\315\255\3462\004/\251\'\205+\341~d\275\350\"\313\204\313"
|
||||
deterministic_key {
|
||||
chain_code: ":JV\362\341\275\220\370r\031@\272\225,\307B\v\023\017\277\b\02000\261\225\026\355J\b\316G"
|
||||
chain_code: "5\037!\360\335\017\276\231\273\3531\020\253\223 \312\240M+\250\2520e\006\034\214{\331\376\201\004\306"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 1
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\375\317\3177\306\272\204\344\210\367\203\326\tn\306\376\322\004\264\r36W\262/!\t>FN\215\302"
|
||||
public_key: "\003\000\n\256n\324$.\324\365\231\f\224\001\376\266\341\036Q\212\374>\245\324\\8*\342\370\251x\b-"
|
||||
deterministic_key {
|
||||
chain_code: "\005\2717\377\3625\362\017`\270\370k\301B\241C[\350\213\244m{L&C\244\250\200$\f\025\357"
|
||||
chain_code: "5\202n|A\251$y+t\005\365\231\357\323\264E\266l\220\367\211dA\306\370\247<\'\034\323\324"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 2
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\031\256\332?\356\255\270o\001\232\327\262\207@\275\315\355\336]\002\020\v\302)\361\037U\223\372\233\266e"
|
||||
public_key: "\002\313/\026\020\254\240\3455\216\342E\300\316\353m.\270\204\264\327\220H\326E9\310\227 \023~\204\215"
|
||||
deterministic_key {
|
||||
chain_code: "$\211\377\t\276\033I!*\320\003\316\260Bl\r^ w\276\300\025\251\ak\317\342\034@9\204\374"
|
||||
chain_code: "\342\263a\033~\374\234UN\034\302\300\370\232\347B#L\251\267\035\255\210\356\vE\264\210\317\030]t"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 3
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\273\222i0kH\005\313e\373\306c\021\340u\275\353\231\224i\333\357\017r\372\200\036PW\311\356,"
|
||||
public_key: "\002\217\n\021GL\354\214\354WhX\254\351\337w.\211&q1o\003\033\330\352**\351\356\210\264m"
|
||||
deterministic_key {
|
||||
chain_code: "f\315\357Y0\037\033\377)|\234\273\267\234\324\000\251\263#&\\\255tZ\313+\0003Hn\022"
|
||||
chain_code: "\036\216\345\320e\267p\241\000\204\254\370\251d\000\253\354\316RH\275RS\221\016\343=T\236\335\222P"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 4
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\300\022\330\270/Jy2\246\226\266\310t\344\241Q\342r\275\027\a\326:\377\230\343\037t\032\351V\207"
|
||||
public_key: "\003\325\n\347\346\3273\312J\211e\335?\227\236\304i\227\377J\222;\253\017\213\371\235d\220\231\026aV"
|
||||
deterministic_key {
|
||||
chain_code: "\372\232\306\242\340P\251\037\227\222z\311\260\f\350 \2627@\223\247\333= \2118\331\344\006\236\362m"
|
||||
chain_code: "YSn>5\364i(j\b\326\212,\f,\322\3200\230\210)\366g\201\274\232\356\027\212O\345\215"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 5
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\350\257\214\317@\262\314sC\021[\000\201;(\000\253\326\275\335\233\'1\206\252\242@B/Fl\266"
|
||||
public_key: "\003\264\331\220\207*\342T\277\323\363\210\266\335\300\245?\024d\002\021\263|\253\035\253\244D\023\004\200\212X"
|
||||
deterministic_key {
|
||||
chain_code: "\2714Rw\317\230\001\356h\203\216z\230xL~[lR\032\275\247\277\362r\333q\220\242`\206\275"
|
||||
chain_code: "yP\342|\327\364\034\f\302}\236\032\031\t\345h(q7\346?wR\221\325\370\021\225\334\317Bg"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 6
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\361z\203\341\345\350\214L\272\262\301-8/\246xX\'\r\027\026#^M\a\313\277\356\354B\022"
|
||||
public_key: "\002HX\261\035\270!\263\2232-F\334\226n=<\0178\270^\202\225\264PF\v#\bdP/\355"
|
||||
deterministic_key {
|
||||
chain_code: "\242\3452\270\275\321\363\206#\310\206\222\2359%tH\364\343\271\266\372I\204U\031Y\325CIbY"
|
||||
chain_code: "Z#\227\222\225\303\203\006q\206\321\v\355\353\220#Oh\360]\001IQD\333\025\356\276\342\270\021\313"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 7
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003l\021W\350G\026kc\225\213\307Rv1[p\270P\r\266T\275\021\b\270\335\'\270\254\307\242:"
|
||||
public_key: "\002\020C\2310\227\302\342\274u\217\021h\270\235\356\326_\365\321\261\272\340\267\n\335~\360\343\"Ow\b"
|
||||
deterministic_key {
|
||||
chain_code: "\364E\240q\263\227Y\200\361q/\212X\343i\234\226\235\036+\n\036&\203(\341\002\235\270\021U\342"
|
||||
chain_code: "\232\000\3117\235\003`)\021g}/\203tk\201\021\364\247\245;\253\321\202\207\342\265\267_<\206\224"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 8
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003KaP\210J\320\354\202\024#*#\323\276i\\\004\341\225\253qw_\235\371\370\316\315N\rZ\031"
|
||||
public_key: "\002\276\211n\305\3339[D\337+\034\263\267U0\263\3039}/\376\207\030\364K\335\301\245\311\241\3419"
|
||||
deterministic_key {
|
||||
chain_code: "\2561\251Rw\2434%\304\v]\020\220d\370\234<\217\214\306\363\361\033\262\204\265}#\224\333\255\031"
|
||||
chain_code: "B\232\f\')\277\034\316HOdn\213\b\204\361\030\357YS \365zY\2749e\260)\233.-"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 9
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\250\371\347\214\240t\242\355\277\231\3351\227g\222\375\363[\326p9\244\032\305^}\003)\000\035\252E"
|
||||
public_key: "\002h\356\202\222P\204x\345\226\017\256/E\304\273{)\272\034\375\2451\321\257\233\372?\320\352\356\271K"
|
||||
deterministic_key {
|
||||
chain_code: "\362\203\2555\335\3013\037\361\200-\245i\225\024\322\274V#;\3157`$\360\206\332?/P]\034"
|
||||
chain_code: "\035\222\325\fY\221(\006\tf#7\370\355el\377\276\245\354\002\327\320\247\315V\004\016v\367\351\225"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 10
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\263\220\a\311h`\216?m\375\232V\205\025zi,`\203\252{\323,&\247\304\263\006K\035j\261"
|
||||
public_key: "\002\325\313@\"\320\035\277(\245\222\342{\374g\235\203\347\217\035\204j\027\034\244\021bY0\247P`\323"
|
||||
deterministic_key {
|
||||
chain_code: "\251K\330\274\360\254q\267\005\3331\2716\277M\3544\352S\006\243\317\223\305Y\304\317\r#\233\362H"
|
||||
chain_code: "\226~!\327\210.\033\214\251\2367\205<\226`UF\354\234/\365\267E\317\202\354\211P\244\221\336\200"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 11
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\336\201guA0\314$\016\335\016xTY\237I\327Zx\217\365K,k\334g\211\202\3770\247X"
|
||||
public_key: "\002\225b\3515\202\233\335\320.7\265\274uh\230N\242\254\317J\364\331\2345\220)\362\334\216\202\\"
|
||||
deterministic_key {
|
||||
chain_code: "WV#4$\027\034m\023\353\235U\021,\327\303\327[\b\003\255$\024\243v\2306\276\230/\273\021"
|
||||
chain_code: "\202:\344\3109?\350\345\001\314(\244q\370\233Rk\261}\302(\275\326\305R\342:\246\036\nV\330"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 0
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\221\322\332>W&\00475\374\317jP\021\332[[\276\363\016\2636\322:\321\361\032!?q-\320"
|
||||
public_key: "\003>K!8\222VEL\371\305 z\aD8\020\233\330S\251T\330\201V\026-k2\227\266;"
|
||||
deterministic_key {
|
||||
chain_code: "\036\364!\212\223\235\037\333\346\215o\344MD4\303\206\215\327M\354.\210\201c\353\267\254\245\250\257\273"
|
||||
chain_code: "\223\265.\200\316\361\241{\223\342c\212\0213ym+\032=#\360\333X\003\2770Z\311\335\267\342\313"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 1
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\204\311|\002}\002\201IQ\003c\253\335Ay\220@3\210\001~\345L\216u\030\217\232\262m{\371"
|
||||
public_key: "\003\331t\251d\023\355w\221\266\301\264\306T\252\350\200\260A\220\363\212\345\021\222\236\003\210\215\342\r\251\000"
|
||||
deterministic_key {
|
||||
chain_code: "\036\026\334\313\264\227\025Y\n\367X8\b\355F,\262h\2246\373\203M1\355\254>\320\r5M\r"
|
||||
chain_code: "\276\262\033\030\227\271&e\254\377\346\031\2112\344[\234Z\221-\033\306P,Mi\021\313r\031\317\341"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 2
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\376WS\201\255et\362H\372\261\233\332\265\250\266Y\344\336y\240\'\025\374\222\274\261\351\032\212\313"
|
||||
public_key: "\002D\374\231\027\306\310\251\261\200\350@\ro\314\216\037>rp\017\276Q\203\027\016\213\320\206VqO\237"
|
||||
deterministic_key {
|
||||
chain_code: "N_\376\r\372n\000\263\353\v\220Z\254\023\307z)M\243g\200L\305\tU\n\n\354+C\016\277"
|
||||
chain_code: "_K4\n\356\235\036\243O\261\200\004\367\324\305;1\247I\350*\353`\204\004d\202\302\335\200/#"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 3
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\000\344v\304py\001-]ut\245\32027\265\367R\331\026o\v\372|\213b1\343\356\250#"
|
||||
public_key: "\003\370\352\3530]|\262\270]5\361\263\255)\027f\342\262\272a-\275\006\302\266\236\344\332\364\r\260\321"
|
||||
deterministic_key {
|
||||
chain_code: "\030@\276\337|\300\303\255\262\374\001\222\023\240%\220\274\306=\242$\213\356\355URv2\210\257\350\201"
|
||||
chain_code: "o!GH\357\030\264\003_S\305\204\234wO\344.\215\377\232\025\206\351\030\227,\303%U2x\225"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 4
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002P\254\2652\374\234\312\250<h\b/&\223\022\343<*\266\317\372\305\373\320J\246\324\321\357y\2736"
|
||||
public_key: "\002\221\021\370a[\205\267\036\021\366`\036\371\253Yk\r\303\025\f\255\2768\310\212\234\221\333\344\340t"
|
||||
deterministic_key {
|
||||
chain_code: "\327\343\333W\312\005\321\a\271`\354\265>\325\300\212\367\217F\275~\370\200\270T\260\323\317\030\200\240\242"
|
||||
chain_code: "\370~\245F\n\307\377Q:\v\207\245\336F\376\2443R\034\346\b\372\b\\o\303\204D#}\266"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 5
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\000\323\225^\225\032\275R\267\347\213\256\033-\252\302\322`%fL\326\bo\337\367c\232\241\310\354\330"
|
||||
public_key: "\002c\034w@c\225\257n~G\330\002\241^\264\231\030\025\220gr\202`u\b\262\361\312\246\202J\341"
|
||||
deterministic_key {
|
||||
chain_code: "z\335|\370>\237\231\311ML3\360/\371\203\243#\037\3555\a%\231]4\213\310=\332\316\002\232"
|
||||
chain_code: "\\\2542\003\022\254\361*\a/4\307\3430\322\303\v\205\351\027\260 l\332\326\235<\363v\020\232"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 6
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\310\264dd\275\026\211\247\324\221\207edi\353\036\246\350\366\370\264\213\266\357_\332x}gI\367-"
|
||||
public_key: "\003\266\304\006g\244l\271>\364\357G8B\374\026w\316\022\205\313\220\274\273>$\350\212o!\rt\230"
|
||||
deterministic_key {
|
||||
chain_code: "\031\\\223*!\004\361\353|\347.\274\032P\275\337\n\224\233\230\216\2660\246\241\311\t>\255\016\313\204"
|
||||
chain_code: "6]\325WN\017o\255\314\213\344\201f\204\361\235\'\343\217\341m\327\326=T\2018g\324\261`\335"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 7
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\226\253\321\200\001\346u\020_C9\nj\001} \212\027\341-f\f=\320~\311\200ck@\361\341"
|
||||
public_key: "\003X\331\344\227G\366//<V\226\b\352#\315\307j\263\232\273d\236)\004\225fk\304\000XM\305"
|
||||
deterministic_key {
|
||||
chain_code: "\253\201\367\346\275\232\320\314\276\005\373\031\316\355\270\276(D\220\364\343\310\370\347\272\2759\232s\300\2218"
|
||||
chain_code: "&\025?\264\a\2334-\203\217\240R\221[{8)9\221\346bv=ut\346\226KVj\2659"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 8
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\0036\201\035\327\312\220\'\360\325B\276\372\347\aFp\265\252\vs\243\245\210\004y\236\250>\353[U"
|
||||
public_key: "\003\307\273B\334\212\303\025r\212\264|\250c\204\\=\360w\335\300\353\266\273\3209\260nl3\271+"
|
||||
deterministic_key {
|
||||
chain_code: "\306#\361\242\241\016-\346\341\330\325\331\352\231\220X\267y\207\302\020\353#\345\0033{\345\353\244\3362"
|
||||
chain_code: "\345\365\034\261\316\2121R\226/+\267K\326C&\236\246],\224\001\220\347\334\351\223K\023\252\360\023"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 9
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003J\371[{Vs\232A\260\343\376!\265\a\031`\0239\277=jd\n\230\270\034\350#\302}x\334"
|
||||
public_key: "\002+[\230[E\225\225R2\350X=\366\343\244\237\260\220J\311\376\200@\\\334\312y\212\276\223\350\267"
|
||||
deterministic_key {
|
||||
chain_code: "c\330\261\301\001\215\307\v\374M\231B7!/x/\215\341\265\312\027b+%\032\304\322z\304`\254"
|
||||
chain_code: "\250W]}O:@\t\016\311\016\335\016\271\260\327\261\237\030G\334\246\233\352t\266\\S\311\333m*"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 10
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002LOV+\260\017\024lxz\021\236Xv\000X\324e\244\037\243\325\325f\003vs*]\260\340\035"
|
||||
public_key: "\002\357\\\252\376]\023\315\'\316`\317\362\032@\232\"\360\331\335\221] `\016,\351<\b\300\225\032m"
|
||||
creation_timestamp: 100000000
|
||||
deterministic_key {
|
||||
chain_code: "\377\340\2459\230\210\367\361\362\205\267\244#\t#\360\215\221_\302v\315{\200Y\210\224\"\243\272\256\301"
|
||||
chain_code: "\370\017\223\021O?.@gZ|\233j\3437\317q-\241!J \323\'\264s\203\314\321\v\346"
|
||||
path: 2147483648
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\264\r,\017e\213\016W\372\024W\215z\022C@+A\2720G\016\034\353\202\312\372\251\206\035r"
|
||||
public_key: "\002\361V\216\001\371p\270\212\272\236%\216\356o\025g\r\035>a\305j\001P\217Q\242\261.\353\367\315"
|
||||
deterministic_key {
|
||||
chain_code: "\000Mm\373e\255\363\373\'\265A\003\247\320U\305\340\342\233\033\034\312zTR\006\347Yu\362b\366"
|
||||
chain_code: "\231B\211S[\216\237\277q{a\365\216\325\250\223s\v\n(\364\257@3c\312rix\260c\217"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
issued_subkeys: 2
|
||||
|
@ -17,9 +17,9 @@ deterministic_key {
|
|||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\330b\034\023\320\217|!\271p\034\017p\330!\245\233j\376\b\316\373\231D\324\271d\217h\217\016^"
|
||||
public_key: "\0022\n\252\267NDr.7i7\332\232x\367\204G-|\204\301\333G\033g\300O\241\006\217\366\370"
|
||||
deterministic_key {
|
||||
chain_code: "\367j\245\025U\265\346\v\234\275\343\rd\214q\004\232\253\312\222Hi\305\201\370`^\304\210\034p*"
|
||||
chain_code: "\213\237\327\245a\273\274\310\377\360\351\352<\211k\033g\0251>y\236\345Jb\244[\b\fO\0311"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
issued_subkeys: 1
|
||||
|
@ -27,207 +27,207 @@ deterministic_key {
|
|||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\306\337\017!F\303;\257Z\320:w\353\304\021L#\250\255\345X\023k\233\323\273\253\331s\352\362\024"
|
||||
public_key: "\002O_Q\223\337\360\245\234\322b_op\b?\030\364\255l\206\344`w\274\204\"\257\235U<}\377"
|
||||
deterministic_key {
|
||||
chain_code: "RS\20672^\r\265\fNCd\305\235\266\a\232\033\303\316\230\376FK\322\314\300}\335zk\016"
|
||||
chain_code: "\331\233\342\227\336r\212>\021\022p\347* +\220\021{\206\310Z\314\335\322\230\331\365\221}\321\036\035"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 0
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\341#\025-h\212\273XE\211\266\224|\222\251\335\375?\275A\350rU\341\212\361\221\267\303\313I\t"
|
||||
public_key: "\003\270\311\006\363\375\002{\310\254n\301\366\303\315\255\3462\004/\251\'\205+\341~d\275\350\"\313\204\313"
|
||||
deterministic_key {
|
||||
chain_code: ":JV\362\341\275\220\370r\031@\272\225,\307B\v\023\017\277\b\02000\261\225\026\355J\b\316G"
|
||||
chain_code: "5\037!\360\335\017\276\231\273\3531\020\253\223 \312\240M+\250\2520e\006\034\214{\331\376\201\004\306"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 1
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\375\317\3177\306\272\204\344\210\367\203\326\tn\306\376\322\004\264\r36W\262/!\t>FN\215\302"
|
||||
public_key: "\003\000\n\256n\324$.\324\365\231\f\224\001\376\266\341\036Q\212\374>\245\324\\8*\342\370\251x\b-"
|
||||
deterministic_key {
|
||||
chain_code: "\005\2717\377\3625\362\017`\270\370k\301B\241C[\350\213\244m{L&C\244\250\200$\f\025\357"
|
||||
chain_code: "5\202n|A\251$y+t\005\365\231\357\323\264E\266l\220\367\211dA\306\370\247<\'\034\323\324"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 2
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\031\256\332?\356\255\270o\001\232\327\262\207@\275\315\355\336]\002\020\v\302)\361\037U\223\372\233\266e"
|
||||
public_key: "\002\313/\026\020\254\240\3455\216\342E\300\316\353m.\270\204\264\327\220H\326E9\310\227 \023~\204\215"
|
||||
deterministic_key {
|
||||
chain_code: "$\211\377\t\276\033I!*\320\003\316\260Bl\r^ w\276\300\025\251\ak\317\342\034@9\204\374"
|
||||
chain_code: "\342\263a\033~\374\234UN\034\302\300\370\232\347B#L\251\267\035\255\210\356\vE\264\210\317\030]t"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 3
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\273\222i0kH\005\313e\373\306c\021\340u\275\353\231\224i\333\357\017r\372\200\036PW\311\356,"
|
||||
public_key: "\002\217\n\021GL\354\214\354WhX\254\351\337w.\211&q1o\003\033\330\352**\351\356\210\264m"
|
||||
deterministic_key {
|
||||
chain_code: "f\315\357Y0\037\033\377)|\234\273\267\234\324\000\251\263#&\\\255tZ\313+\0003Hn\022"
|
||||
chain_code: "\036\216\345\320e\267p\241\000\204\254\370\251d\000\253\354\316RH\275RS\221\016\343=T\236\335\222P"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 4
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\300\022\330\270/Jy2\246\226\266\310t\344\241Q\342r\275\027\a\326:\377\230\343\037t\032\351V\207"
|
||||
public_key: "\003\325\n\347\346\3273\312J\211e\335?\227\236\304i\227\377J\222;\253\017\213\371\235d\220\231\026aV"
|
||||
deterministic_key {
|
||||
chain_code: "\372\232\306\242\340P\251\037\227\222z\311\260\f\350 \2627@\223\247\333= \2118\331\344\006\236\362m"
|
||||
chain_code: "YSn>5\364i(j\b\326\212,\f,\322\3200\230\210)\366g\201\274\232\356\027\212O\345\215"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 5
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\350\257\214\317@\262\314sC\021[\000\201;(\000\253\326\275\335\233\'1\206\252\242@B/Fl\266"
|
||||
public_key: "\003\264\331\220\207*\342T\277\323\363\210\266\335\300\245?\024d\002\021\263|\253\035\253\244D\023\004\200\212X"
|
||||
deterministic_key {
|
||||
chain_code: "\2714Rw\317\230\001\356h\203\216z\230xL~[lR\032\275\247\277\362r\333q\220\242`\206\275"
|
||||
chain_code: "yP\342|\327\364\034\f\302}\236\032\031\t\345h(q7\346?wR\221\325\370\021\225\334\317Bg"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 6
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\361z\203\341\345\350\214L\272\262\301-8/\246xX\'\r\027\026#^M\a\313\277\356\354B\022"
|
||||
public_key: "\002HX\261\035\270!\263\2232-F\334\226n=<\0178\270^\202\225\264PF\v#\bdP/\355"
|
||||
deterministic_key {
|
||||
chain_code: "\242\3452\270\275\321\363\206#\310\206\222\2359%tH\364\343\271\266\372I\204U\031Y\325CIbY"
|
||||
chain_code: "Z#\227\222\225\303\203\006q\206\321\v\355\353\220#Oh\360]\001IQD\333\025\356\276\342\270\021\313"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 7
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003l\021W\350G\026kc\225\213\307Rv1[p\270P\r\266T\275\021\b\270\335\'\270\254\307\242:"
|
||||
public_key: "\002\020C\2310\227\302\342\274u\217\021h\270\235\356\326_\365\321\261\272\340\267\n\335~\360\343\"Ow\b"
|
||||
deterministic_key {
|
||||
chain_code: "\364E\240q\263\227Y\200\361q/\212X\343i\234\226\235\036+\n\036&\203(\341\002\235\270\021U\342"
|
||||
chain_code: "\232\000\3117\235\003`)\021g}/\203tk\201\021\364\247\245;\253\321\202\207\342\265\267_<\206\224"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 8
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003KaP\210J\320\354\202\024#*#\323\276i\\\004\341\225\253qw_\235\371\370\316\315N\rZ\031"
|
||||
public_key: "\002\276\211n\305\3339[D\337+\034\263\267U0\263\3039}/\376\207\030\364K\335\301\245\311\241\3419"
|
||||
deterministic_key {
|
||||
chain_code: "\2561\251Rw\2434%\304\v]\020\220d\370\234<\217\214\306\363\361\033\262\204\265}#\224\333\255\031"
|
||||
chain_code: "B\232\f\')\277\034\316HOdn\213\b\204\361\030\357YS \365zY\2749e\260)\233.-"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 9
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\250\371\347\214\240t\242\355\277\231\3351\227g\222\375\363[\326p9\244\032\305^}\003)\000\035\252E"
|
||||
public_key: "\002h\356\202\222P\204x\345\226\017\256/E\304\273{)\272\034\375\2451\321\257\233\372?\320\352\356\271K"
|
||||
deterministic_key {
|
||||
chain_code: "\362\203\2555\335\3013\037\361\200-\245i\225\024\322\274V#;\3157`$\360\206\332?/P]\034"
|
||||
chain_code: "\035\222\325\fY\221(\006\tf#7\370\355el\377\276\245\354\002\327\320\247\315V\004\016v\367\351\225"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 10
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\263\220\a\311h`\216?m\375\232V\205\025zi,`\203\252{\323,&\247\304\263\006K\035j\261"
|
||||
public_key: "\002\325\313@\"\320\035\277(\245\222\342{\374g\235\203\347\217\035\204j\027\034\244\021bY0\247P`\323"
|
||||
deterministic_key {
|
||||
chain_code: "\251K\330\274\360\254q\267\005\3331\2716\277M\3544\352S\006\243\317\223\305Y\304\317\r#\233\362H"
|
||||
chain_code: "\226~!\327\210.\033\214\251\2367\205<\226`UF\354\234/\365\267E\317\202\354\211P\244\221\336\200"
|
||||
path: 2147483648
|
||||
path: 0
|
||||
path: 11
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\336\201guA0\314$\016\335\016xTY\237I\327Zx\217\365K,k\334g\211\202\3770\247X"
|
||||
public_key: "\002\225b\3515\202\233\335\320.7\265\274uh\230N\242\254\317J\364\331\2345\220)\362\334\216\202\\"
|
||||
deterministic_key {
|
||||
chain_code: "WV#4$\027\034m\023\353\235U\021,\327\303\327[\b\003\255$\024\243v\2306\276\230/\273\021"
|
||||
chain_code: "\202:\344\3109?\350\345\001\314(\244q\370\233Rk\261}\302(\275\326\305R\342:\246\036\nV\330"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 0
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002\221\322\332>W&\00475\374\317jP\021\332[[\276\363\016\2636\322:\321\361\032!?q-\320"
|
||||
public_key: "\003>K!8\222VEL\371\305 z\aD8\020\233\330S\251T\330\201V\026-k2\227\266;"
|
||||
deterministic_key {
|
||||
chain_code: "\036\364!\212\223\235\037\333\346\215o\344MD4\303\206\215\327M\354.\210\201c\353\267\254\245\250\257\273"
|
||||
chain_code: "\223\265.\200\316\361\241{\223\342c\212\0213ym+\032=#\360\333X\003\2770Z\311\335\267\342\313"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 1
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\204\311|\002}\002\201IQ\003c\253\335Ay\220@3\210\001~\345L\216u\030\217\232\262m{\371"
|
||||
public_key: "\003\331t\251d\023\355w\221\266\301\264\306T\252\350\200\260A\220\363\212\345\021\222\236\003\210\215\342\r\251\000"
|
||||
deterministic_key {
|
||||
chain_code: "\036\026\334\313\264\227\025Y\n\367X8\b\355F,\262h\2246\373\203M1\355\254>\320\r5M\r"
|
||||
chain_code: "\276\262\033\030\227\271&e\254\377\346\031\2112\344[\234Z\221-\033\306P,Mi\021\313r\031\317\341"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 2
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\376WS\201\255et\362H\372\261\233\332\265\250\266Y\344\336y\240\'\025\374\222\274\261\351\032\212\313"
|
||||
public_key: "\002D\374\231\027\306\310\251\261\200\350@\ro\314\216\037>rp\017\276Q\203\027\016\213\320\206VqO\237"
|
||||
deterministic_key {
|
||||
chain_code: "N_\376\r\372n\000\263\353\v\220Z\254\023\307z)M\243g\200L\305\tU\n\n\354+C\016\277"
|
||||
chain_code: "_K4\n\356\235\036\243O\261\200\004\367\324\305;1\247I\350*\353`\204\004d\202\302\335\200/#"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 3
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\000\344v\304py\001-]ut\245\32027\265\367R\331\026o\v\372|\213b1\343\356\250#"
|
||||
public_key: "\003\370\352\3530]|\262\270]5\361\263\255)\027f\342\262\272a-\275\006\302\266\236\344\332\364\r\260\321"
|
||||
deterministic_key {
|
||||
chain_code: "\030@\276\337|\300\303\255\262\374\001\222\023\240%\220\274\306=\242$\213\356\355URv2\210\257\350\201"
|
||||
chain_code: "o!GH\357\030\264\003_S\305\204\234wO\344.\215\377\232\025\206\351\030\227,\303%U2x\225"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 4
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\002P\254\2652\374\234\312\250<h\b/&\223\022\343<*\266\317\372\305\373\320J\246\324\321\357y\2736"
|
||||
public_key: "\002\221\021\370a[\205\267\036\021\366`\036\371\253Yk\r\303\025\f\255\2768\310\212\234\221\333\344\340t"
|
||||
deterministic_key {
|
||||
chain_code: "\327\343\333W\312\005\321\a\271`\354\265>\325\300\212\367\217F\275~\370\200\270T\260\323\317\030\200\240\242"
|
||||
chain_code: "\370~\245F\n\307\377Q:\v\207\245\336F\376\2443R\034\346\b\372\b\\o\303\204D#}\266"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 5
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\000\323\225^\225\032\275R\267\347\213\256\033-\252\302\322`%fL\326\bo\337\367c\232\241\310\354\330"
|
||||
public_key: "\002c\034w@c\225\257n~G\330\002\241^\264\231\030\025\220gr\202`u\b\262\361\312\246\202J\341"
|
||||
deterministic_key {
|
||||
chain_code: "z\335|\370>\237\231\311ML3\360/\371\203\243#\037\3555\a%\231]4\213\310=\332\316\002\232"
|
||||
chain_code: "\\\2542\003\022\254\361*\a/4\307\3430\322\303\v\205\351\027\260 l\332\326\235<\363v\020\232"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 6
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\310\264dd\275\026\211\247\324\221\207edi\353\036\246\350\366\370\264\213\266\357_\332x}gI\367-"
|
||||
public_key: "\003\266\304\006g\244l\271>\364\357G8B\374\026w\316\022\205\313\220\274\273>$\350\212o!\rt\230"
|
||||
deterministic_key {
|
||||
chain_code: "\031\\\223*!\004\361\353|\347.\274\032P\275\337\n\224\233\230\216\2660\246\241\311\t>\255\016\313\204"
|
||||
chain_code: "6]\325WN\017o\255\314\213\344\201f\204\361\235\'\343\217\341m\327\326=T\2018g\324\261`\335"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 7
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003\226\253\321\200\001\346u\020_C9\nj\001} \212\027\341-f\f=\320~\311\200ck@\361\341"
|
||||
public_key: "\003X\331\344\227G\366//<V\226\b\352#\315\307j\263\232\273d\236)\004\225fk\304\000XM\305"
|
||||
deterministic_key {
|
||||
chain_code: "\253\201\367\346\275\232\320\314\276\005\373\031\316\355\270\276(D\220\364\343\310\370\347\272\2759\232s\300\2218"
|
||||
chain_code: "&\025?\264\a\2334-\203\217\240R\221[{8)9\221\346bv=ut\346\226KVj\2659"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 8
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\0036\201\035\327\312\220\'\360\325B\276\372\347\aFp\265\252\vs\243\245\210\004y\236\250>\353[U"
|
||||
public_key: "\003\307\273B\334\212\303\025r\212\264|\250c\204\\=\360w\335\300\353\266\273\3209\260nl3\271+"
|
||||
deterministic_key {
|
||||
chain_code: "\306#\361\242\241\016-\346\341\330\325\331\352\231\220X\267y\207\302\020\353#\345\0033{\345\353\244\3362"
|
||||
chain_code: "\345\365\034\261\316\2121R\226/+\267K\326C&\236\246],\224\001\220\347\334\351\223K\023\252\360\023"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 9
|
||||
}
|
||||
|
||||
type: DETERMINISTIC_KEY
|
||||
public_key: "\003J\371[{Vs\232A\260\343\376!\265\a\031`\0239\277=jd\n\230\270\034\350#\302}x\334"
|
||||
public_key: "\002+[\230[E\225\225R2\350X=\366\343\244\237\260\220J\311\376\200@\\\334\312y\212\276\223\350\267"
|
||||
deterministic_key {
|
||||
chain_code: "c\330\261\301\001\215\307\v\374M\231B7!/x/\215\341\265\312\027b+%\032\304\322z\304`\254"
|
||||
chain_code: "\250W]}O:@\t\016\311\016\335\016\271\260\327\261\237\030G\334\246\233\352t\266\\S\311\333m*"
|
||||
path: 2147483648
|
||||
path: 1
|
||||
path: 10
|
||||
|
|
|
@ -86,10 +86,10 @@ message Key {
|
|||
ENCRYPTED_SCRYPT_AES = 2;
|
||||
|
||||
/**
|
||||
* Not really a key, but rather contains the seed for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
*/
|
||||
DETERMINISTIC_ROOT_SEED = 3;
|
||||
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
*/
|
||||
DETERMINISTIC_MNEMONIC = 3;
|
||||
|
||||
/**
|
||||
* A key that was derived deterministically. Note that the root seed that created it may NOT be present in the
|
||||
|
@ -99,13 +99,6 @@ message Key {
|
|||
* key can be rederived on the fly.
|
||||
*/
|
||||
DETERMINISTIC_KEY = 4;
|
||||
|
||||
/**
|
||||
* Not really a key, but rather contains the mnemonic phrase for a deterministic key hierarchy in the private_key field.
|
||||
* The label and public_key fields are missing. Creation timestamp will exist.
|
||||
* Must be immediately after DETERMINISTIC_KEY
|
||||
*/
|
||||
DETERMINISTIC_MNEMONIC = 5;
|
||||
}
|
||||
required Type type = 1;
|
||||
|
||||
|
@ -116,7 +109,7 @@ message Key {
|
|||
optional EncryptedData encrypted_data = 6;
|
||||
|
||||
// The public EC key derived from the private key. We allow both to be stored to avoid mobile clients having to
|
||||
// do lots of slow EC math on startup. For DETERMINISTIC_ROOT_SEED and DETERMINISTIC_MNEMONIC entries this is missing.
|
||||
// do lots of slow EC math on startup. For DETERMINISTIC_MNEMONIC entries this is missing.
|
||||
optional bytes public_key = 3;
|
||||
|
||||
// User-provided label associated with the key.
|
||||
|
|
Loading…
Add table
Reference in a new issue