From 6445ea5f13850f42c3952bd06a2369317683ed88 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Thu, 8 Jan 2015 13:48:49 -0800 Subject: Break project up into Java and Android build/test. --- .../libaxolotl/SessionCipherTest.java | 198 +++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 tests/src/main/java/org/whispersystems/libaxolotl/SessionCipherTest.java (limited to 'tests/src/main/java/org/whispersystems/libaxolotl/SessionCipherTest.java') diff --git a/tests/src/main/java/org/whispersystems/libaxolotl/SessionCipherTest.java b/tests/src/main/java/org/whispersystems/libaxolotl/SessionCipherTest.java new file mode 100644 index 00000000..e956ed77 --- /dev/null +++ b/tests/src/main/java/org/whispersystems/libaxolotl/SessionCipherTest.java @@ -0,0 +1,198 @@ +package org.whispersystems.libaxolotl; + +import junit.framework.TestCase; + +import org.whispersystems.libaxolotl.ecc.Curve; +import org.whispersystems.libaxolotl.ecc.ECKeyPair; +import org.whispersystems.libaxolotl.ecc.ECPublicKey; +import org.whispersystems.libaxolotl.protocol.CiphertextMessage; +import org.whispersystems.libaxolotl.protocol.WhisperMessage; +import org.whispersystems.libaxolotl.ratchet.AliceAxolotlParameters; +import org.whispersystems.libaxolotl.ratchet.BobAxolotlParameters; +import org.whispersystems.libaxolotl.ratchet.RatchetingSession; +import org.whispersystems.libaxolotl.state.AxolotlStore; +import org.whispersystems.libaxolotl.state.SessionRecord; +import org.whispersystems.libaxolotl.state.SessionState; +import org.whispersystems.libaxolotl.util.guava.Optional; + +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Random; + + +public class SessionCipherTest extends TestCase { + + public void testBasicSessionV2() + throws InvalidKeyException, DuplicateMessageException, + LegacyMessageException, InvalidMessageException, NoSuchAlgorithmException, NoSessionException + { + SessionRecord aliceSessionRecord = new SessionRecord(); + SessionRecord bobSessionRecord = new SessionRecord(); + + initializeSessionsV2(aliceSessionRecord.getSessionState(), bobSessionRecord.getSessionState()); + runInteraction(aliceSessionRecord, bobSessionRecord); + } + + public void testBasicSessionV3() + throws InvalidKeyException, DuplicateMessageException, + LegacyMessageException, InvalidMessageException, NoSuchAlgorithmException, NoSessionException + { + SessionRecord aliceSessionRecord = new SessionRecord(); + SessionRecord bobSessionRecord = new SessionRecord(); + + initializeSessionsV3(aliceSessionRecord.getSessionState(), bobSessionRecord.getSessionState()); + runInteraction(aliceSessionRecord, bobSessionRecord); + } + + private void runInteraction(SessionRecord aliceSessionRecord, SessionRecord bobSessionRecord) + throws DuplicateMessageException, LegacyMessageException, InvalidMessageException, NoSuchAlgorithmException, NoSessionException { + AxolotlStore aliceStore = new InMemoryAxolotlStore(); + AxolotlStore bobStore = new InMemoryAxolotlStore(); + + aliceStore.storeSession(2L, 1, aliceSessionRecord); + bobStore.storeSession(3L, 1, bobSessionRecord); + + SessionCipher aliceCipher = new SessionCipher(aliceStore, 2L, 1); + SessionCipher bobCipher = new SessionCipher(bobStore, 3L, 1); + + byte[] alicePlaintext = "This is a plaintext message.".getBytes(); + CiphertextMessage message = aliceCipher.encrypt(alicePlaintext); + byte[] bobPlaintext = bobCipher.decrypt(new WhisperMessage(message.serialize())); + + assertTrue(Arrays.equals(alicePlaintext, bobPlaintext)); + + byte[] bobReply = "This is a message from Bob.".getBytes(); + CiphertextMessage reply = bobCipher.encrypt(bobReply); + byte[] receivedReply = aliceCipher.decrypt(new WhisperMessage(reply.serialize())); + + assertTrue(Arrays.equals(bobReply, receivedReply)); + + List aliceCiphertextMessages = new ArrayList<>(); + List alicePlaintextMessages = new ArrayList<>(); + + for (int i=0;i<50;i++) { + alicePlaintextMessages.add(("смерть за смерть " + i).getBytes()); + aliceCiphertextMessages.add(aliceCipher.encrypt(("смерть за смерть " + i).getBytes())); + } + + long seed = System.currentTimeMillis(); + + Collections.shuffle(aliceCiphertextMessages, new Random(seed)); + Collections.shuffle(alicePlaintextMessages, new Random(seed)); + + for (int i=0;i bobCiphertextMessages = new ArrayList<>(); + List bobPlaintextMessages = new ArrayList<>(); + + for (int i=0;i<20;i++) { + bobPlaintextMessages.add(("смерть за смерть " + i).getBytes()); + bobCiphertextMessages.add(bobCipher.encrypt(("смерть за смерть " + i).getBytes())); + } + + seed = System.currentTimeMillis(); + + Collections.shuffle(bobCiphertextMessages, new Random(seed)); + Collections.shuffle(bobPlaintextMessages, new Random(seed)); + + for (int i=0;iabsent()) + .create(); + + BobAxolotlParameters bobParameters = BobAxolotlParameters.newBuilder() + .setOurIdentityKey(bobIdentityKey) + .setOurOneTimePreKey(Optional.absent()) + .setOurRatchetKey(bobEphemeralKey) + .setOurSignedPreKey(bobBaseKey) + .setTheirBaseKey(aliceBaseKey.getPublicKey()) + .setTheirIdentityKey(aliceIdentityKey.getPublicKey()) + .create(); + + RatchetingSession.initializeSession(aliceSessionState, 2, aliceParameters); + RatchetingSession.initializeSession(bobSessionState, 2, bobParameters); + } + + private void initializeSessionsV3(SessionState aliceSessionState, SessionState bobSessionState) + throws InvalidKeyException + { + ECKeyPair aliceIdentityKeyPair = Curve.generateKeyPair(); + IdentityKeyPair aliceIdentityKey = new IdentityKeyPair(new IdentityKey(aliceIdentityKeyPair.getPublicKey()), + aliceIdentityKeyPair.getPrivateKey()); + ECKeyPair aliceBaseKey = Curve.generateKeyPair(); + ECKeyPair aliceEphemeralKey = Curve.generateKeyPair(); + + ECKeyPair alicePreKey = aliceBaseKey; + + ECKeyPair bobIdentityKeyPair = Curve.generateKeyPair(); + IdentityKeyPair bobIdentityKey = new IdentityKeyPair(new IdentityKey(bobIdentityKeyPair.getPublicKey()), + bobIdentityKeyPair.getPrivateKey()); + ECKeyPair bobBaseKey = Curve.generateKeyPair(); + ECKeyPair bobEphemeralKey = bobBaseKey; + + ECKeyPair bobPreKey = Curve.generateKeyPair(); + + AliceAxolotlParameters aliceParameters = AliceAxolotlParameters.newBuilder() + .setOurBaseKey(aliceBaseKey) + .setOurIdentityKey(aliceIdentityKey) + .setTheirOneTimePreKey(Optional.absent()) + .setTheirRatchetKey(bobEphemeralKey.getPublicKey()) + .setTheirSignedPreKey(bobBaseKey.getPublicKey()) + .setTheirIdentityKey(bobIdentityKey.getPublicKey()) + .create(); + + BobAxolotlParameters bobParameters = BobAxolotlParameters.newBuilder() + .setOurRatchetKey(bobEphemeralKey) + .setOurSignedPreKey(bobBaseKey) + .setOurOneTimePreKey(Optional.absent()) + .setOurIdentityKey(bobIdentityKey) + .setTheirIdentityKey(aliceIdentityKey.getPublicKey()) + .setTheirBaseKey(aliceBaseKey.getPublicKey()) + .create(); + + RatchetingSession.initializeSession(aliceSessionState, 3, aliceParameters); + RatchetingSession.initializeSession(bobSessionState, 3, bobParameters); + } +} -- cgit v1.2.3