mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-07-30 19:41:24 +00:00
Use Bouncy Castle's Scrypt implementation rather than the standalone library.
Amazingly, on a Pixel 2 this implementation is a bit quicker than Will Glozer/Colin Percival's native code.
This commit is contained in:
@@ -9,7 +9,6 @@ eclipse.project.name = 'bitcoinj-core'
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile 'org.bouncycastle:bcprov-jdk15on:1.60'
|
compile 'org.bouncycastle:bcprov-jdk15on:1.60'
|
||||||
implementation 'com.lambdaworks:scrypt:1.4.0'
|
|
||||||
implementation 'com.google.guava:guava:27.0.1-android'
|
implementation 'com.google.guava:guava:27.0.1-android'
|
||||||
compile 'com.google.protobuf:protobuf-java:3.6.1'
|
compile 'com.google.protobuf:protobuf-java:3.6.1'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
|
implementation 'com.squareup.okhttp3:okhttp:3.12.1'
|
||||||
|
@@ -17,8 +17,9 @@
|
|||||||
package org.bitcoinj.crypto;
|
package org.bitcoinj.crypto;
|
||||||
|
|
||||||
import org.bitcoinj.core.*;
|
import org.bitcoinj.core.*;
|
||||||
|
import org.bouncycastle.crypto.generators.SCrypt;
|
||||||
|
|
||||||
import com.google.common.primitives.Bytes;
|
import com.google.common.primitives.Bytes;
|
||||||
import com.lambdaworks.crypto.SCrypt;
|
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
@@ -126,7 +127,7 @@ public class BIP38PrivateKey extends PrefixedChecksummedBytes {
|
|||||||
|
|
||||||
private ECKey decryptNoEC(String normalizedPassphrase) {
|
private ECKey decryptNoEC(String normalizedPassphrase) {
|
||||||
try {
|
try {
|
||||||
byte[] derived = SCrypt.scrypt(normalizedPassphrase.getBytes(StandardCharsets.UTF_8), addressHash, 16384, 8, 8, 64);
|
byte[] derived = SCrypt.generate(normalizedPassphrase.getBytes(StandardCharsets.UTF_8), addressHash, 16384, 8, 8, 64);
|
||||||
byte[] key = Arrays.copyOfRange(derived, 32, 64);
|
byte[] key = Arrays.copyOfRange(derived, 32, 64);
|
||||||
SecretKeySpec keyspec = new SecretKeySpec(key, "AES");
|
SecretKeySpec keyspec = new SecretKeySpec(key, "AES");
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ public class BIP38PrivateKey extends PrefixedChecksummedBytes {
|
|||||||
byte[] ownerEntropy = Arrays.copyOfRange(content, 0, 8);
|
byte[] ownerEntropy = Arrays.copyOfRange(content, 0, 8);
|
||||||
byte[] ownerSalt = hasLotAndSequence ? Arrays.copyOfRange(ownerEntropy, 0, 4) : ownerEntropy;
|
byte[] ownerSalt = hasLotAndSequence ? Arrays.copyOfRange(ownerEntropy, 0, 4) : ownerEntropy;
|
||||||
|
|
||||||
byte[] passFactorBytes = SCrypt.scrypt(normalizedPassphrase.getBytes(StandardCharsets.UTF_8), ownerSalt, 16384, 8, 8, 32);
|
byte[] passFactorBytes = SCrypt.generate(normalizedPassphrase.getBytes(StandardCharsets.UTF_8), ownerSalt, 16384, 8, 8, 32);
|
||||||
if (hasLotAndSequence) {
|
if (hasLotAndSequence) {
|
||||||
byte[] hashBytes = Bytes.concat(passFactorBytes, ownerEntropy);
|
byte[] hashBytes = Bytes.concat(passFactorBytes, ownerEntropy);
|
||||||
checkState(hashBytes.length == 40);
|
checkState(hashBytes.length == 40);
|
||||||
@@ -159,7 +160,7 @@ public class BIP38PrivateKey extends PrefixedChecksummedBytes {
|
|||||||
|
|
||||||
byte[] salt = Bytes.concat(addressHash, ownerEntropy);
|
byte[] salt = Bytes.concat(addressHash, ownerEntropy);
|
||||||
checkState(salt.length == 12);
|
checkState(salt.length == 12);
|
||||||
byte[] derived = SCrypt.scrypt(k.getPubKey(), salt, 1024, 1, 1, 64);
|
byte[] derived = SCrypt.generate(k.getPubKey(), salt, 1024, 1, 1, 64);
|
||||||
byte[] aeskey = Arrays.copyOfRange(derived, 32, 64);
|
byte[] aeskey = Arrays.copyOfRange(derived, 32, 64);
|
||||||
|
|
||||||
SecretKeySpec keyspec = new SecretKeySpec(aeskey, "AES");
|
SecretKeySpec keyspec = new SecretKeySpec(aeskey, "AES");
|
||||||
|
@@ -20,12 +20,12 @@ package org.bitcoinj.crypto;
|
|||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.protobuf.ByteString;
|
import com.google.protobuf.ByteString;
|
||||||
import com.lambdaworks.crypto.SCrypt;
|
|
||||||
import org.bitcoinj.core.Utils;
|
import org.bitcoinj.core.Utils;
|
||||||
import org.bitcoinj.wallet.Protos;
|
import org.bitcoinj.wallet.Protos;
|
||||||
import org.bitcoinj.wallet.Protos.ScryptParameters;
|
import org.bitcoinj.wallet.Protos.ScryptParameters;
|
||||||
import org.bitcoinj.wallet.Protos.Wallet.EncryptionType;
|
import org.bitcoinj.wallet.Protos.Wallet.EncryptionType;
|
||||||
import org.bouncycastle.crypto.engines.AESEngine;
|
import org.bouncycastle.crypto.engines.AESEngine;
|
||||||
|
import org.bouncycastle.crypto.generators.SCrypt;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.bouncycastle.crypto.BufferedBlockCipher;
|
import org.bouncycastle.crypto.BufferedBlockCipher;
|
||||||
@@ -157,7 +157,7 @@ public class KeyCrypterScrypt implements KeyCrypter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Stopwatch watch = Stopwatch.createStarted();
|
final Stopwatch watch = Stopwatch.createStarted();
|
||||||
byte[] keyBytes = SCrypt.scrypt(passwordBytes, salt, (int) scryptParameters.getN(), scryptParameters.getR(), scryptParameters.getP(), KEY_LENGTH);
|
byte[] keyBytes = SCrypt.generate(passwordBytes, salt, (int) scryptParameters.getN(), scryptParameters.getR(), scryptParameters.getP(), KEY_LENGTH);
|
||||||
watch.stop();
|
watch.stop();
|
||||||
log.info("Deriving key took {} for {} scrypt iterations.", watch, scryptParameters.getN());
|
log.info("Deriving key took {} for {} scrypt iterations.", watch, scryptParameters.getN());
|
||||||
return new KeyParameter(keyBytes);
|
return new KeyParameter(keyBytes);
|
||||||
|
Reference in New Issue
Block a user