Speed up tests with Scrypt and reduce memory consumption by reducing the number of iterations.

This commit is contained in:
Andreas Schildbach 2019-03-31 00:21:49 +01:00
parent 5570b0b476
commit 0df0591c0b
4 changed files with 21 additions and 46 deletions

View file

@ -25,15 +25,11 @@ import org.bitcoinj.crypto.TransactionSignature;
import org.bitcoinj.params.MainNetParams;
import org.bitcoinj.params.TestNet3Params;
import org.bitcoinj.params.UnitTestParams;
import org.bitcoinj.utils.BriefLogFormatter;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.protobuf.ByteString;
import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.Protos.ScryptParameters;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
@ -59,6 +55,7 @@ public class ECKeyTest {
private KeyCrypter keyCrypter;
private static final int SCRYPT_ITERATIONS = 256;
private static CharSequence PASSWORD1 = "my hovercraft has eels";
private static CharSequence WRONG_PASSWORD = "it is a snowy day today";
private static final NetworkParameters TESTNET = TestNet3Params.get();
@ -67,11 +64,7 @@ public class ECKeyTest {
@Before
public void setUp() throws Exception {
Protos.ScryptParameters.Builder scryptParametersBuilder = Protos.ScryptParameters.newBuilder().setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()));
ScryptParameters scryptParameters = scryptParametersBuilder.build();
keyCrypter = new KeyCrypterScrypt(scryptParameters);
BriefLogFormatter.init();
keyCrypter = new KeyCrypterScrypt(SCRYPT_ITERATIONS);
}
@Test

View file

@ -33,6 +33,7 @@ public class ChildKeyDerivationTest {
private static final NetworkParameters TESTNET = TestNet3Params.get();
private static final NetworkParameters UNITTEST = UnitTestParams.get();
private static final int SCRYPT_ITERATIONS = 256;
private static final int HDW_CHAIN_EXTERNAL = 0;
private static final int HDW_CHAIN_INTERNAL = 1;
@ -142,7 +143,7 @@ public class ChildKeyDerivationTest {
public void encryptedDerivation() throws Exception {
// Check that encrypting a parent key in the hierarchy and then deriving from it yields a DeterministicKey
// with no private key component, and that the private key bytes are derived on demand.
KeyCrypter scrypter = new KeyCrypterScrypt();
KeyCrypter scrypter = new KeyCrypterScrypt(SCRYPT_ITERATIONS);
KeyParameter aesKey = scrypter.deriveKey("we never went to the moon");
DeterministicKey key1 = HDKeyDerivation.createMasterPrivateKey("it was all a hoax".getBytes());

View file

@ -17,21 +17,19 @@
package org.bitcoinj.crypto;
import org.bitcoinj.core.Utils;
import org.bitcoinj.utils.BriefLogFormatter;
import com.google.protobuf.ByteString;
import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.Protos.ScryptParameters;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Random;
import java.util.UUID;
import static org.junit.Assert.*;
import org.bitcoinj.core.Utils;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KeyCrypterScryptTest {
@ -40,26 +38,20 @@ public class KeyCrypterScryptTest {
// Nonsense bytes for encryption test.
private static final byte[] TEST_BYTES1 = {0, -101, 2, 103, -4, 105, 6, 107, 8, -109, 10, 111, -12, 113, 14, -115, 16, 117, -18, 119, 20, 121, 22, 123, -24, 125, 26, 127, -28, 29, -30, 31};
private static final int SCRYPT_ITERATIONS = 256;
private static final CharSequence PASSWORD1 = "aTestPassword";
private static final CharSequence PASSWORD2 = "0123456789";
private static final CharSequence WRONG_PASSWORD = "thisIsTheWrongPassword";
private ScryptParameters scryptParameters;
private KeyCrypterScrypt keyCrypter;
@Before
public void setUp() throws Exception {
Protos.ScryptParameters.Builder scryptParametersBuilder = Protos.ScryptParameters.newBuilder()
.setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()));
scryptParameters = scryptParametersBuilder.build();
BriefLogFormatter.init();
keyCrypter = new KeyCrypterScrypt(SCRYPT_ITERATIONS);
}
@Test
public void testKeyCrypterGood1() throws KeyCrypterException {
KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters);
// Encrypt.
EncryptedData data = keyCrypter.encrypt(TEST_BYTES1, keyCrypter.deriveKey(PASSWORD1));
assertNotNull(data);
@ -78,8 +70,6 @@ public class KeyCrypterScryptTest {
*/
@Test
public void testKeyCrypterGood2() {
KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters);
// Trying random UUIDs for plainText and passwords.
int numberOfTests = 16;
for (int i = 0; i < numberOfTests; i++) {
@ -98,8 +88,6 @@ public class KeyCrypterScryptTest {
@Test
public void testKeyCrypterWrongPassword() throws KeyCrypterException {
KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters);
// create a longer encryption string
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 100; i++) {
@ -120,8 +108,6 @@ public class KeyCrypterScryptTest {
@Test
public void testEncryptDecryptBytes1() throws KeyCrypterException {
KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters);
// Encrypt bytes.
EncryptedData data = keyCrypter.encrypt(TEST_BYTES1, keyCrypter.deriveKey(PASSWORD1));
assertNotNull(data);
@ -136,8 +122,6 @@ public class KeyCrypterScryptTest {
@Test
public void testEncryptDecryptBytes2() throws KeyCrypterException {
KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters);
// Encrypt random bytes of various lengths up to length 50.
Random random = new Random();

View file

@ -61,7 +61,6 @@ import org.easymock.EasyMock;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.protobuf.ByteString;
import org.bitcoinj.wallet.KeyChain.KeyPurpose;
import org.bitcoinj.wallet.Protos.Wallet.EncryptionType;
@ -93,6 +92,7 @@ import static org.junit.Assert.*;
public class WalletTest extends TestWithWallet {
private static final Logger log = LoggerFactory.getLogger(WalletTest.class);
private static final int SCRYPT_ITERATIONS = 256;
private static final CharSequence PASSWORD1 = "my helicopter contains eels";
private static final CharSequence WRONG_PASSWORD = "nothing noone nobody nowhere";
@ -2124,10 +2124,7 @@ public class WalletTest extends TestWithWallet {
// Try added an ECKey that was encrypted with a differenct ScryptParameters (i.e. a non-homogenous key).
// This is not allowed as the ScryptParameters is stored at the Wallet level.
Protos.ScryptParameters.Builder scryptParametersBuilder = Protos.ScryptParameters.newBuilder()
.setSalt(ByteString.copyFrom(KeyCrypterScrypt.randomSalt()));
Protos.ScryptParameters scryptParameters = scryptParametersBuilder.build();
KeyCrypter keyCrypterDifferent = new KeyCrypterScrypt(scryptParameters);
KeyCrypter keyCrypterDifferent = new KeyCrypterScrypt();
ECKey ecKeyDifferent = new ECKey();
ecKeyDifferent = ecKeyDifferent.encrypt(keyCrypterDifferent, aesKey);
encryptedWallet.importKey(ecKeyDifferent);
@ -3321,7 +3318,7 @@ public class WalletTest extends TestWithWallet {
assertTrue(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2PKH));
assertTrue(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2WPKH));
KeyParameter aesKey = new KeyCrypterScrypt().deriveKey("abc");
KeyParameter aesKey = new KeyCrypterScrypt(SCRYPT_ITERATIONS).deriveKey("abc");
wallet.encrypt(new KeyCrypterScrypt(), aesKey);
assertTrue(wallet.isEncrypted());
try {
@ -3375,7 +3372,7 @@ public class WalletTest extends TestWithWallet {
assertTrue(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2PKH));
assertTrue(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2WPKH));
KeyParameter aesKey = new KeyCrypterScrypt().deriveKey("abc");
KeyParameter aesKey = new KeyCrypterScrypt(SCRYPT_ITERATIONS).deriveKey("abc");
wallet.encrypt(new KeyCrypterScrypt(), aesKey);
assertTrue(wallet.isEncrypted());
try {
@ -3417,7 +3414,7 @@ public class WalletTest extends TestWithWallet {
assertFalse(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2PKH));
assertTrue(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2WPKH));
KeyParameter aesKey = new KeyCrypterScrypt().deriveKey("abc");
KeyParameter aesKey = new KeyCrypterScrypt(SCRYPT_ITERATIONS).deriveKey("abc");
wallet.encrypt(new KeyCrypterScrypt(), aesKey);
assertTrue(wallet.isEncrypted());
assertEquals(Script.ScriptType.P2PKH, wallet.currentReceiveAddress().getOutputScriptType());