Improved tests for cryptography

This commit is contained in:
Christian Basler 2016-02-09 17:09:22 +01:00
parent 60adf73616
commit af3e63f592
3 changed files with 71 additions and 24 deletions

View File

@ -38,8 +38,6 @@ public class CryptoBox implements Streamable {
private final byte[] mac; private final byte[] mac;
private byte[] encrypted; private byte[] encrypted;
private long addressVersion;
public CryptoBox(Streamable data, byte[] K) throws IOException { public CryptoBox(Streamable data, byte[] K) throws IOException {
this(Encode.bytes(data), K); this(Encode.bytes(data), K);

View File

@ -4,19 +4,24 @@ import ch.dissem.bitmessage.InternalContext;
import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography; import ch.dissem.bitmessage.cryptography.bc.BouncyCryptography;
import ch.dissem.bitmessage.entity.ObjectMessage; import ch.dissem.bitmessage.entity.ObjectMessage;
import ch.dissem.bitmessage.entity.payload.GenericPayload; import ch.dissem.bitmessage.entity.payload.GenericPayload;
import ch.dissem.bitmessage.entity.valueobject.PrivateKey;
import ch.dissem.bitmessage.ports.MultiThreadedPOWEngine; import ch.dissem.bitmessage.ports.MultiThreadedPOWEngine;
import ch.dissem.bitmessage.ports.ProofOfWorkEngine; import ch.dissem.bitmessage.ports.ProofOfWorkEngine;
import ch.dissem.bitmessage.utils.CallbackWaiter; import ch.dissem.bitmessage.utils.CallbackWaiter;
import ch.dissem.bitmessage.utils.Singleton; import ch.dissem.bitmessage.utils.Singleton;
import ch.dissem.bitmessage.utils.UnixTime; import ch.dissem.bitmessage.utils.UnixTime;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import javax.xml.bind.DatatypeConverter; import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import static ch.dissem.bitmessage.utils.UnixTime.DAY;
import static ch.dissem.bitmessage.utils.UnixTime.MINUTE; import static ch.dissem.bitmessage.utils.UnixTime.MINUTE;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -33,50 +38,51 @@ public class CryptographyTest {
public static final byte[] TEST_RIPEMD160 = DatatypeConverter.parseHexBinary("" public static final byte[] TEST_RIPEMD160 = DatatypeConverter.parseHexBinary(""
+ "cd566972b5e50104011a92b59fa8e0b1234851ae"); + "cd566972b5e50104011a92b59fa8e0b1234851ae");
private static BouncyCryptography security; private static BouncyCryptography crypto;
public CryptographyTest() { @BeforeClass
security = new BouncyCryptography(); public static void setUp() {
Singleton.initialize(security); crypto = new BouncyCryptography();
Singleton.initialize(crypto);
InternalContext ctx = mock(InternalContext.class); InternalContext ctx = mock(InternalContext.class);
when(ctx.getProofOfWorkEngine()).thenReturn(new MultiThreadedPOWEngine()); when(ctx.getProofOfWorkEngine()).thenReturn(new MultiThreadedPOWEngine());
security.setContext(ctx); crypto.setContext(ctx);
} }
@Test @Test
public void testRipemd160() { public void testRipemd160() {
assertArrayEquals(TEST_RIPEMD160, security.ripemd160(TEST_VALUE)); assertArrayEquals(TEST_RIPEMD160, crypto.ripemd160(TEST_VALUE));
} }
@Test @Test
public void testSha1() { public void testSha1() {
assertArrayEquals(TEST_SHA1, security.sha1(TEST_VALUE)); assertArrayEquals(TEST_SHA1, crypto.sha1(TEST_VALUE));
} }
@Test @Test
public void testSha512() { public void testSha512() {
assertArrayEquals(TEST_SHA512, security.sha512(TEST_VALUE)); assertArrayEquals(TEST_SHA512, crypto.sha512(TEST_VALUE));
} }
@Test @Test
public void testChaining() { public void testChaining() {
assertArrayEquals(TEST_SHA512, security.sha512("test".getBytes(), "string".getBytes())); assertArrayEquals(TEST_SHA512, crypto.sha512("test".getBytes(), "string".getBytes()));
} }
@Test @Test
public void testDoubleHash() { public void ensureDoubleHashYieldsSameResultAsHashOfHash() {
assertArrayEquals(security.sha512(TEST_SHA512), security.doubleSha512(TEST_VALUE)); assertArrayEquals(crypto.sha512(TEST_SHA512), crypto.doubleSha512(TEST_VALUE));
} }
@Test(expected = IOException.class) @Test(expected = IOException.class)
public void testProofOfWorkFails() throws IOException { public void ensureExceptionForInsufficientProofOfWork() throws IOException {
ObjectMessage objectMessage = new ObjectMessage.Builder() ObjectMessage objectMessage = new ObjectMessage.Builder()
.nonce(new byte[8]) .nonce(new byte[8])
.expiresTime(UnixTime.now(+2 * MINUTE)) .expiresTime(UnixTime.now(+28 * DAY))
.objectType(0) .objectType(0)
.payload(GenericPayload.read(0, new ByteArrayInputStream(new byte[0]), 1, 0)) .payload(GenericPayload.read(0, new ByteArrayInputStream(new byte[0]), 1, 0))
.build(); .build();
security.checkProofOfWork(objectMessage, 1000, 1000); crypto.checkProofOfWork(objectMessage, 1000, 1000);
} }
@Test @Test
@ -88,7 +94,7 @@ public class CryptographyTest {
.payload(GenericPayload.read(0, new ByteArrayInputStream(new byte[0]), 1, 0)) .payload(GenericPayload.read(0, new ByteArrayInputStream(new byte[0]), 1, 0))
.build(); .build();
final CallbackWaiter<byte[]> waiter = new CallbackWaiter<>(); final CallbackWaiter<byte[]> waiter = new CallbackWaiter<>();
security.doProofOfWork(objectMessage, 1000, 1000, crypto.doProofOfWork(objectMessage, 1000, 1000,
new ProofOfWorkEngine.Callback() { new ProofOfWorkEngine.Callback() {
@Override @Override
public void onNonceCalculated(byte[] initialHash, byte[] nonce) { public void onNonceCalculated(byte[] initialHash, byte[] nonce) {
@ -96,6 +102,52 @@ public class CryptographyTest {
} }
}); });
objectMessage.setNonce(waiter.waitForValue()); objectMessage.setNonce(waiter.waitForValue());
security.checkProofOfWork(objectMessage, 1000, 1000); crypto.checkProofOfWork(objectMessage, 1000, 1000);
}
@Test
public void ensureEncryptionAndDecryptionWorks() {
byte[] data = crypto.randomBytes(100);
byte[] key_e = crypto.randomBytes(32);
byte[] iv = crypto.randomBytes(16);
byte[] encrypted = crypto.crypt(true, data, key_e, iv);
byte[] decrypted = crypto.crypt(false, encrypted, key_e, iv);
assertArrayEquals(data, decrypted);
}
@Test(expected = IllegalArgumentException.class)
public void ensureDecryptionFailsWithInvalidCypherText() {
byte[] data = crypto.randomBytes(128);
byte[] key_e = crypto.randomBytes(32);
byte[] iv = crypto.randomBytes(16);
crypto.crypt(false, data, key_e, iv);
}
@Test
public void testMultiplication() {
byte[] a = crypto.randomBytes(PrivateKey.PRIVATE_KEY_SIZE);
byte[] A = crypto.createPublicKey(a);
byte[] b = crypto.randomBytes(PrivateKey.PRIVATE_KEY_SIZE);
byte[] B = crypto.createPublicKey(b);
assertArrayEquals(crypto.multiply(A, b), crypto.multiply(B, a));
}
@Test
public void ensureSignatureIsValid() {
byte[] data = crypto.randomBytes(100);
PrivateKey privateKey = new PrivateKey(false, 1, 1000, 1000);
byte[] signature = crypto.getSignature(data, privateKey);
assertThat(crypto.isSignatureValid(data, signature, privateKey.getPubkey()), is(true));
}
@Test
public void ensureSignatureIsInvalidForTemperedData() {
byte[] data = crypto.randomBytes(100);
PrivateKey privateKey = new PrivateKey(false, 1, 1000, 1000);
byte[] signature = crypto.getSignature(data, privateKey);
data[0]++;
assertThat(crypto.isSignatureValid(data, signature, privateKey.getPubkey()), is(false));
} }
} }

View File

@ -30,7 +30,6 @@ import org.junit.Test;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Random;
import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG; import static ch.dissem.bitmessage.entity.Plaintext.Type.MSG;
import static ch.dissem.bitmessage.utils.Singleton.security; import static ch.dissem.bitmessage.utils.Singleton.security;
@ -42,8 +41,6 @@ public class JdbcMessageRepositoryTest extends TestBase {
private BitmessageAddress contactB; private BitmessageAddress contactB;
private BitmessageAddress identity; private BitmessageAddress identity;
private TestJdbcConfig config;
private AddressRepository addressRepo;
private MessageRepository repo; private MessageRepository repo;
private Label inbox; private Label inbox;
@ -52,9 +49,9 @@ public class JdbcMessageRepositoryTest extends TestBase {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
config = new TestJdbcConfig(); TestJdbcConfig config = new TestJdbcConfig();
config.reset(); config.reset();
addressRepo = new JdbcAddressRepository(config); AddressRepository addressRepo = new JdbcAddressRepository(config);
repo = new JdbcMessageRepository(config); repo = new JdbcMessageRepository(config);
new InternalContext(new BitmessageContext.Builder() new InternalContext(new BitmessageContext.Builder()
.cryptography(security()) .cryptography(security())