Test BQP implementation

This commit is contained in:
str4d
2016-03-16 08:35:23 +00:00
parent c3997fb06f
commit 5ff7adcebf
2 changed files with 398 additions and 0 deletions

View File

@@ -15,6 +15,8 @@ dependencies {
compile project(':briar-desktop')
compile "junit:junit:4.12"
compile "org.jmock:jmock:2.8.1"
compile "org.jmock:jmock-junit4:2.8.1"
compile "org.jmock:jmock-legacy:2.8.1"
compile "org.hamcrest:hamcrest-library:1.3"
compile "org.hamcrest:hamcrest-core:1.3"
}
@@ -23,6 +25,8 @@ dependencyVerification {
verify = [
'junit:junit:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
'org.jmock:jmock:75d4bdaf636879f0215830c5e6ab99407069a625eaffde5d57b32d887b75dc14',
'org.jmock:jmock-junit4:81e3fff46ed56738a6f3f5147525d1d85cda591ce5df007cc193e735cee31113',
'org.jmock:jmock-legacy:19c76059eb254775ba884fc8039bc5c7d1700dc68cc55ad3be5b405a2a8a1819',
'org.hamcrest:hamcrest-library:711d64522f9ec410983bd310934296da134be4254a125080a0416ec178dfad1c',
'org.hamcrest:hamcrest-core:66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9',
]

View File

@@ -0,0 +1,394 @@
package org.briarproject.keyagreement;
import org.briarproject.BriarTestCase;
import org.briarproject.TestUtils;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.PublicKey;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.keyagreement.Payload;
import org.briarproject.api.keyagreement.PayloadEncoder;
import org.briarproject.util.StringUtils;
import org.jmock.Expectations;
import org.jmock.auto.Mock;
import org.jmock.integration.junit4.JUnitRuleMockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Rule;
import org.junit.Test;
import static org.briarproject.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
public class KeyAgreementProtocolTest extends BriarTestCase {
@Rule
public JUnitRuleMockery context = new JUnitRuleMockery() {{
// So we can mock concrete classes like KeyAgreementTransport
setImposteriser(ClassImposteriser.INSTANCE);
}};
private static final byte[] ALICE_PUBKEY = TestUtils.getRandomBytes(32);
private static final byte[] ALICE_COMMIT =
TestUtils.getRandomBytes(COMMIT_LENGTH);
private static final byte[] ALICE_PAYLOAD =
TestUtils.getRandomBytes(COMMIT_LENGTH + 8);
private static final byte[] BOB_PUBKEY = TestUtils.getRandomBytes(32);
private static final byte[] BOB_COMMIT =
TestUtils.getRandomBytes(COMMIT_LENGTH);
private static final byte[] BOB_PAYLOAD =
TestUtils.getRandomBytes(COMMIT_LENGTH + 19);
private static final byte[] ALICE_CONFIRM =
TestUtils.getRandomBytes(SecretKey.LENGTH);
private static final byte[] BOB_CONFIRM =
TestUtils.getRandomBytes(SecretKey.LENGTH);
private static final byte[] BAD_PUBKEY = TestUtils.getRandomBytes(32);
private static final byte[] BAD_COMMIT =
TestUtils.getRandomBytes(COMMIT_LENGTH);
private static final byte[] BAD_CONFIRM =
TestUtils.getRandomBytes(SecretKey.LENGTH);
@Mock
KeyAgreementProtocol.Callbacks callbacks;
@Mock
CryptoComponent crypto;
@Mock
PayloadEncoder payloadEncoder;
@Mock
KeyAgreementTransport transport;
@Mock
PublicKey ourPubKey;
@Test
public void testAliceProtocol() throws Exception {
// set up
final Payload theirPayload = new Payload(BOB_COMMIT, null);
final Payload ourPayload = new Payload(ALICE_COMMIT, null);
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
final SecretKey sharedSecret = TestUtils.createSecretKey();
final SecretKey masterSecret = TestUtils.createSecretKey();
KeyAgreementProtocol protocol =
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
transport, theirPayload, ourPayload, ourKeyPair, true);
// expectations
context.checking(new Expectations() {{
// Helpers
allowing(payloadEncoder).encode(ourPayload);
will(returnValue(ALICE_PAYLOAD));
allowing(payloadEncoder).encode(theirPayload);
will(returnValue(BOB_PAYLOAD));
allowing(ourPubKey).getEncoded();
will(returnValue(ALICE_PUBKEY));
// Alice sends her public key
oneOf(transport).sendKey(ALICE_PUBKEY);
// Alice receives Bob's public key
oneOf(callbacks).connectionWaiting();
oneOf(transport).receiveKey();
will(returnValue(BOB_PUBKEY));
oneOf(callbacks).initialPacketReceived();
// Alice verifies Bob's public key
oneOf(crypto).deriveKeyCommitment(BOB_PUBKEY);
will(returnValue(BOB_COMMIT));
// Alice computes shared secret
oneOf(crypto).deriveSharedSecret(BOB_PUBKEY, ourKeyPair, true);
will(returnValue(sharedSecret));
// Alice sends her confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, BOB_PAYLOAD,
ALICE_PAYLOAD, BOB_PUBKEY, ourKeyPair, true, true);
will(returnValue(ALICE_CONFIRM));
oneOf(transport).sendConfirm(ALICE_CONFIRM);
// Alice receives Bob's confirmation record
oneOf(transport).receiveConfirm();
will(returnValue(BOB_CONFIRM));
// Alice verifies Bob's confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, BOB_PAYLOAD,
ALICE_PAYLOAD, BOB_PUBKEY, ourKeyPair, true, false);
will(returnValue(BOB_CONFIRM));
// Alice computes master secret
oneOf(crypto).deriveMasterSecret(sharedSecret);
will(returnValue(masterSecret));
}});
// execute
assertThat(masterSecret, is(equalTo(protocol.perform())));
}
@Test
public void testBobProtocol() throws Exception {
// set up
final Payload theirPayload = new Payload(ALICE_COMMIT, null);
final Payload ourPayload = new Payload(BOB_COMMIT, null);
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
final SecretKey sharedSecret = TestUtils.createSecretKey();
final SecretKey masterSecret = TestUtils.createSecretKey();
KeyAgreementProtocol protocol =
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
transport, theirPayload, ourPayload, ourKeyPair, false);
// expectations
context.checking(new Expectations() {{
// Helpers
allowing(payloadEncoder).encode(ourPayload);
will(returnValue(BOB_PAYLOAD));
allowing(payloadEncoder).encode(theirPayload);
will(returnValue(ALICE_PAYLOAD));
allowing(ourPubKey).getEncoded();
will(returnValue(BOB_PUBKEY));
// Bob receives Alice's public key
oneOf(transport).receiveKey();
will(returnValue(ALICE_PUBKEY));
oneOf(callbacks).initialPacketReceived();
// Bob verifies Alice's public key
oneOf(crypto).deriveKeyCommitment(ALICE_PUBKEY);
will(returnValue(ALICE_COMMIT));
// Bob sends his public key
oneOf(transport).sendKey(BOB_PUBKEY);
// Bob computes shared secret
oneOf(crypto).deriveSharedSecret(ALICE_PUBKEY, ourKeyPair, false);
will(returnValue(sharedSecret));
// Bob receives Alices's confirmation record
oneOf(transport).receiveConfirm();
will(returnValue(ALICE_CONFIRM));
// Bob verifies Alice's confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, ALICE_PAYLOAD,
BOB_PAYLOAD, ALICE_PUBKEY, ourKeyPair, false, true);
will(returnValue(ALICE_CONFIRM));
// Bob sends his confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, ALICE_PAYLOAD,
BOB_PAYLOAD, ALICE_PUBKEY, ourKeyPair, false, false);
will(returnValue(BOB_CONFIRM));
oneOf(transport).sendConfirm(BOB_CONFIRM);
// Bob computes master secret
oneOf(crypto).deriveMasterSecret(sharedSecret);
will(returnValue(masterSecret));
}});
// execute
assertThat(masterSecret, is(equalTo(protocol.perform())));
}
@Test(expected = AbortException.class)
public void testAliceProtocolAbortOnBadKey() throws Exception {
// set up
final Payload theirPayload = new Payload(BOB_COMMIT, null);
final Payload ourPayload = new Payload(ALICE_COMMIT, null);
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
KeyAgreementProtocol protocol =
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
transport, theirPayload, ourPayload, ourKeyPair, true);
// expectations
context.checking(new Expectations() {{
// Helpers
allowing(ourPubKey).getEncoded();
will(returnValue(ALICE_PUBKEY));
// Alice sends her public key
oneOf(transport).sendKey(ALICE_PUBKEY);
// Alice receives a bad public key
oneOf(callbacks).connectionWaiting();
oneOf(transport).receiveKey();
will(returnValue(BAD_PUBKEY));
oneOf(callbacks).initialPacketReceived();
// Alice verifies Bob's public key
oneOf(crypto).deriveKeyCommitment(BAD_PUBKEY);
will(returnValue(BAD_COMMIT));
// Alice aborts
oneOf(transport).sendAbort(false);
// Alice never computes shared secret
never(crypto).deriveSharedSecret(BAD_PUBKEY, ourKeyPair, true);
}});
// execute
protocol.perform();
}
@Test(expected = AbortException.class)
public void testBobProtocolAbortOnBadKey() throws Exception {
// set up
final Payload theirPayload = new Payload(ALICE_COMMIT, null);
final Payload ourPayload = new Payload(BOB_COMMIT, null);
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
KeyAgreementProtocol protocol =
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
transport, theirPayload, ourPayload, ourKeyPair, false);
// expectations
context.checking(new Expectations() {{
// Helpers
allowing(ourPubKey).getEncoded();
will(returnValue(BOB_PUBKEY));
// Bob receives a bad public key
oneOf(transport).receiveKey();
will(returnValue(BAD_PUBKEY));
oneOf(callbacks).initialPacketReceived();
// Bob verifies Alice's public key
oneOf(crypto).deriveKeyCommitment(BAD_PUBKEY);
will(returnValue(BAD_COMMIT));
// Bob aborts
oneOf(transport).sendAbort(false);
// Bob never sends his public key
never(transport).sendKey(BOB_PUBKEY);
}});
// execute
protocol.perform();
}
@Test(expected = AbortException.class)
public void testAliceProtocolAbortOnBadConfirm() throws Exception {
// set up
final Payload theirPayload = new Payload(BOB_COMMIT, null);
final Payload ourPayload = new Payload(ALICE_COMMIT, null);
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
final SecretKey sharedSecret = TestUtils.createSecretKey();
KeyAgreementProtocol protocol =
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
transport, theirPayload, ourPayload, ourKeyPair, true);
// expectations
context.checking(new Expectations() {{
// Helpers
allowing(payloadEncoder).encode(ourPayload);
will(returnValue(ALICE_PAYLOAD));
allowing(payloadEncoder).encode(theirPayload);
will(returnValue(BOB_PAYLOAD));
allowing(ourPubKey).getEncoded();
will(returnValue(ALICE_PUBKEY));
// Alice sends her public key
oneOf(transport).sendKey(ALICE_PUBKEY);
// Alice receives Bob's public key
oneOf(callbacks).connectionWaiting();
oneOf(transport).receiveKey();
will(returnValue(BOB_PUBKEY));
oneOf(callbacks).initialPacketReceived();
// Alice verifies Bob's public key
oneOf(crypto).deriveKeyCommitment(BOB_PUBKEY);
will(returnValue(BOB_COMMIT));
// Alice computes shared secret
oneOf(crypto).deriveSharedSecret(BOB_PUBKEY, ourKeyPair, true);
will(returnValue(sharedSecret));
// Alice sends her confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, BOB_PAYLOAD,
ALICE_PAYLOAD, BOB_PUBKEY, ourKeyPair, true, true);
will(returnValue(ALICE_CONFIRM));
oneOf(transport).sendConfirm(ALICE_CONFIRM);
// Alice receives a bad confirmation record
oneOf(transport).receiveConfirm();
will(returnValue(BAD_CONFIRM));
// Alice verifies Bob's confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, BOB_PAYLOAD,
ALICE_PAYLOAD, BOB_PUBKEY, ourKeyPair, true, false);
will(returnValue(BOB_CONFIRM));
// Alice aborts
oneOf(transport).sendAbort(false);
// Alice never computes master secret
never(crypto).deriveMasterSecret(sharedSecret);
}});
// execute
protocol.perform();
}
@Test(expected = AbortException.class)
public void testBobProtocolAbortOnBadConfirm() throws Exception {
// set up
final Payload theirPayload = new Payload(ALICE_COMMIT, null);
final Payload ourPayload = new Payload(BOB_COMMIT, null);
final KeyPair ourKeyPair = new KeyPair(ourPubKey, null);
final SecretKey sharedSecret = TestUtils.createSecretKey();
KeyAgreementProtocol protocol =
new KeyAgreementProtocol(callbacks, crypto, payloadEncoder,
transport, theirPayload, ourPayload, ourKeyPair, false);
// expectations
context.checking(new Expectations() {{
// Helpers
allowing(payloadEncoder).encode(ourPayload);
will(returnValue(BOB_PAYLOAD));
allowing(payloadEncoder).encode(theirPayload);
will(returnValue(ALICE_PAYLOAD));
allowing(ourPubKey).getEncoded();
will(returnValue(BOB_PUBKEY));
// Bob receives Alice's public key
oneOf(transport).receiveKey();
will(returnValue(ALICE_PUBKEY));
oneOf(callbacks).initialPacketReceived();
// Bob verifies Alice's public key
oneOf(crypto).deriveKeyCommitment(ALICE_PUBKEY);
will(returnValue(ALICE_COMMIT));
// Bob sends his public key
oneOf(transport).sendKey(BOB_PUBKEY);
// Bob computes shared secret
oneOf(crypto).deriveSharedSecret(ALICE_PUBKEY, ourKeyPair, false);
will(returnValue(sharedSecret));
// Bob receives a bad confirmation record
oneOf(transport).receiveConfirm();
will(returnValue(BAD_CONFIRM));
// Bob verifies Alice's confirmation record
oneOf(crypto).deriveConfirmationRecord(sharedSecret, ALICE_PAYLOAD,
BOB_PAYLOAD, ALICE_PUBKEY, ourKeyPair, false, true);
will(returnValue(ALICE_CONFIRM));
// Bob aborts
oneOf(transport).sendAbort(false);
// Bob never sends his confirmation record
never(crypto).deriveConfirmationRecord(sharedSecret, ALICE_PAYLOAD,
BOB_PAYLOAD, ALICE_PUBKEY, ourKeyPair, false, false);
}});
// execute
protocol.perform();
}
}