Skip to content

Commit

Permalink
Speed up tests with Scrypt and reduce memory consumption by reducing …
Browse files Browse the repository at this point in the history
…the number of iterations.

(cherry picked from commit 0df0591c0b1ad6fbd20861e98e68146ed4851c64)
Signed-off-by: HashEngineering <[email protected]>
  • Loading branch information
Andreas Schildbach authored and HashEngineering committed Jun 25, 2024
1 parent 143da56 commit 018bef6
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 43 deletions.
11 changes: 2 additions & 9 deletions core/src/test/java/org/bitcoinj/core/ECKeyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@
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;
Expand All @@ -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();
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -143,7 +144,7 @@ public void inverseEqualsNormal() throws Exception {
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());
Expand Down
38 changes: 11 additions & 27 deletions core/src/test/java/org/bitcoinj/crypto/KeyCrypterScryptTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,42 @@

package org.bitcoinj.crypto;

import org.bitcoinj.core.Utils;
import org.bitcoinj.utils.BriefLogFormatter;
import com.google.protobuf.ByteString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;

import java.util.Random;
import java.util.UUID;

import org.bitcoinj.wallet.Protos;
import org.bitcoinj.wallet.Protos.ScryptParameters;
import org.bitcoinj.core.Utils;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;
import java.util.UUID;

import static org.junit.Assert.*;

public class KeyCrypterScryptTest {

private static final Logger log = LoggerFactory.getLogger(KeyCrypterScryptTest.class);

// 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 static final CharSequence WRONG_PASSWORD2 = "anotherWrongPassword";

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);
Expand All @@ -79,8 +71,6 @@ public void testKeyCrypterGood1() throws KeyCrypterException {
*/
@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++) {
Expand All @@ -99,8 +89,6 @@ public void testKeyCrypterGood2() {

@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++) {
Expand All @@ -127,8 +115,6 @@ public void testKeyCrypterWrongPassword() throws KeyCrypterException {

@Test
public void testEncryptDecryptBytes1() throws KeyCrypterException {
KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(scryptParameters);

// Encrypt bytes.
EncryptedData data = keyCrypter.encrypt(TEST_BYTES1, keyCrypter.deriveKey(PASSWORD1));
assertNotNull(data);
Expand All @@ -143,8 +129,6 @@ public void testEncryptDecryptBytes1() throws KeyCrypterException {

@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();

Expand Down
24 changes: 18 additions & 6 deletions core/src/test/java/org/bitcoinj/wallet/WalletTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
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;
Expand Down Expand Up @@ -94,6 +93,7 @@
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";

Expand Down Expand Up @@ -2133,10 +2133,7 @@ public void mismatchedCrypter() throws Exception {

// 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);
Expand Down Expand Up @@ -3337,7 +3334,7 @@ public void upgradeToDeterministic_basic_to_P2PKH_encrypted() throws Exception {
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 {
Expand All @@ -3361,6 +3358,21 @@ public void upgradeToDeterministic_basic_to_P2PKH_encrypted() throws Exception {
assertEquals(Script.ScriptType.P2PKH, wallet.freshReceiveAddress().getOutputScriptType());
}

@Test
public void upgradeToDeterministic_noDowngrade_unencrypted() throws Exception {
wallet = Wallet.createDeterministic(UNITTEST, Script.ScriptType.P2PKH);
assertFalse(wallet.isEncrypted());
assertFalse(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2PKH));
assertEquals(Script.ScriptType.P2PKH, wallet.currentReceiveAddress().getOutputScriptType());
assertEquals(Script.ScriptType.P2PKH, wallet.freshReceiveAddress().getOutputScriptType());

wallet.upgradeToDeterministic(Script.ScriptType.P2PKH, null);
assertFalse(wallet.isEncrypted());
assertFalse(wallet.isDeterministicUpgradeRequired(Script.ScriptType.P2PKH));
assertEquals(Script.ScriptType.P2PKH, wallet.currentReceiveAddress().getOutputScriptType());
assertEquals(Script.ScriptType.P2PKH, wallet.freshReceiveAddress().getOutputScriptType());
}

@Test(expected = IllegalStateException.class)
public void shouldNotAddTransactionSignerThatIsNotReady() throws Exception {
wallet.addTransactionSigner(new NopTransactionSigner(false));
Expand Down

0 comments on commit 018bef6

Please sign in to comment.