diff --git a/briar-android-tests/src/test/java/org/briarproject/SyncIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/SyncIntegrationTest.java
index 3ce9d3b2fc8ca80e0fcd12cac6fc710d97c56bd0..5b8aae38c6ec190c2c74cbe945f219f5cdfa858c 100644
--- a/briar-android-tests/src/test/java/org/briarproject/SyncIntegrationTest.java
+++ b/briar-android-tests/src/test/java/org/briarproject/SyncIntegrationTest.java
@@ -122,7 +122,7 @@ public class SyncIntegrationTest extends BriarTestCase {
 
 		// Create the readers
 		StreamContext ctx = new StreamContext(contactId, transportId, tagKey,
-				headerKey, 0);
+				headerKey, streamNumber);
 		InputStream streamReader = streamReaderFactory.createStreamReader(in,
 				ctx);
 		PacketReader packetReader = packetReaderFactory.createPacketReader(
diff --git a/briar-api/src/org/briarproject/api/transport/TransportConstants.java b/briar-api/src/org/briarproject/api/transport/TransportConstants.java
index 5f126c7a40db6aa23144ca4591ee453ec60acbba..9166bcf0ca387c82f366cc50706d9197727158df 100644
--- a/briar-api/src/org/briarproject/api/transport/TransportConstants.java
+++ b/briar-api/src/org/briarproject/api/transport/TransportConstants.java
@@ -8,11 +8,14 @@ public interface TransportConstants {
 	/** The length of the pseudo-random tag in bytes. */
 	int TAG_LENGTH = 16;
 
-	/** The length of the message authentication code (MAC) in bytes. */
-	int MAC_LENGTH = 16;
+	/** The length of the stream header nonce in bytes. */
+	int STREAM_HEADER_NONCE_LENGTH = 24;
 
 	/** The length of the stream header initialisation vector (IV) in bytes. */
-	int STREAM_HEADER_IV_LENGTH = 24;
+	int STREAM_HEADER_IV_LENGTH = STREAM_HEADER_NONCE_LENGTH - 8;
+
+	/** The length of the message authentication code (MAC) in bytes. */
+	int MAC_LENGTH = 16;
 
 	/** The length of the stream header in bytes. */
 	int STREAM_HEADER_LENGTH = STREAM_HEADER_IV_LENGTH + SecretKey.LENGTH
@@ -42,7 +45,8 @@ public interface TransportConstants {
 	 * support. Streams may be shorter than this length, but all transport
 	 * plugins must support streams of at least this length.
 	 */
-	int MIN_STREAM_LENGTH = 64 * 1024; // 64 KiB
+	int MIN_STREAM_LENGTH = STREAM_HEADER_LENGTH + FRAME_HEADER_LENGTH
+			+ MAC_LENGTH;
 
 	/** The maximum difference in milliseconds between two peers' clocks. */
 	int MAX_CLOCK_DIFFERENCE = 24 * 60 * 60 * 1000; // 24 hours
diff --git a/briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java b/briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java
index 571f80013bda5a4197bf1cafa6ed4156c3eeeb36..c134872b337c70fe53f96c99eb1d976ea4f2fb0c 100644
--- a/briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java
+++ b/briar-core/src/org/briarproject/crypto/StreamDecrypterFactoryImpl.java
@@ -1,15 +1,15 @@
 package org.briarproject.crypto;
 
-import java.io.InputStream;
-
-import javax.inject.Inject;
-import javax.inject.Provider;
-
 import org.briarproject.api.crypto.SecretKey;
 import org.briarproject.api.crypto.StreamDecrypter;
 import org.briarproject.api.crypto.StreamDecrypterFactory;
 import org.briarproject.api.transport.StreamContext;
 
+import java.io.InputStream;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+
 class StreamDecrypterFactoryImpl implements StreamDecrypterFactory {
 
 	private final Provider<AuthenticatedCipher> cipherProvider;
@@ -19,14 +19,17 @@ class StreamDecrypterFactoryImpl implements StreamDecrypterFactory {
 		this.cipherProvider = cipherProvider;
 	}
 
+	@Override
 	public StreamDecrypter createStreamDecrypter(InputStream in,
 			StreamContext ctx) {
 		AuthenticatedCipher cipher = cipherProvider.get();
-		return new StreamDecrypterImpl(in, cipher, ctx.getHeaderKey());
+		return new StreamDecrypterImpl(in, cipher, ctx.getStreamNumber(),
+				ctx.getHeaderKey());
 	}
 
+	@Override
 	public StreamDecrypter createInvitationStreamDecrypter(InputStream in,
 			SecretKey headerKey) {
-		return new StreamDecrypterImpl(in, cipherProvider.get(), headerKey);
+		return new StreamDecrypterImpl(in, cipherProvider.get(), 0, headerKey);
 	}
 }
diff --git a/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java b/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java
index e7a1648de7b89b704a8cdc92fe3524b777a59203..bfd961c92bedfcff7b19e1e877decc4077d90fed 100644
--- a/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java
+++ b/briar-core/src/org/briarproject/crypto/StreamDecrypterImpl.java
@@ -3,6 +3,7 @@ package org.briarproject.crypto;
 import org.briarproject.api.FormatException;
 import org.briarproject.api.crypto.SecretKey;
 import org.briarproject.api.crypto.StreamDecrypter;
+import org.briarproject.util.ByteUtils;
 
 import java.io.EOFException;
 import java.io.IOException;
@@ -17,11 +18,14 @@ import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH
 import static org.briarproject.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
 import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH;
 import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_LENGTH;
+import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_NONCE_LENGTH;
+import static org.briarproject.util.ByteUtils.INT_64_BYTES;
 
 class StreamDecrypterImpl implements StreamDecrypter {
 
 	private final InputStream in;
 	private final AuthenticatedCipher cipher;
+	private final long streamNumber;
 	private final SecretKey streamHeaderKey;
 	private final byte[] frameNonce, frameHeader, frameCiphertext;
 
@@ -30,9 +34,10 @@ class StreamDecrypterImpl implements StreamDecrypter {
 	private boolean finalFrame;
 
 	StreamDecrypterImpl(InputStream in, AuthenticatedCipher cipher,
-			SecretKey streamHeaderKey) {
+			long streamNumber, SecretKey streamHeaderKey) {
 		this.in = in;
 		this.cipher = cipher;
+		this.streamNumber = streamNumber;
 		this.streamHeaderKey = streamHeaderKey;
 		frameNonce = new byte[FRAME_NONCE_LENGTH];
 		frameHeader = new byte[FRAME_HEADER_PLAINTEXT_LENGTH];
@@ -42,6 +47,7 @@ class StreamDecrypterImpl implements StreamDecrypter {
 		finalFrame = false;
 	}
 
+	@Override
 	public int readFrame(byte[] payload) throws IOException {
 		// The buffer must be big enough for a full-size frame
 		if (payload.length < MAX_PAYLOAD_LENGTH)
@@ -103,7 +109,6 @@ class StreamDecrypterImpl implements StreamDecrypter {
 	}
 
 	private void readStreamHeader() throws IOException {
-		byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH];
 		byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
 		byte[] streamHeaderPlaintext = new byte[SecretKey.LENGTH];
 		// Read the stream header
@@ -114,11 +119,14 @@ class StreamDecrypterImpl implements StreamDecrypter {
 			if (read == -1) throw new EOFException();
 			offset += read;
 		}
+		// The nonce consists of the stream number followed by the IV
+		byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
+		ByteUtils.writeUint64(streamNumber, streamHeaderNonce, 0);
+		System.arraycopy(streamHeaderCiphertext, 0, streamHeaderNonce,
+				INT_64_BYTES, STREAM_HEADER_IV_LENGTH);
 		// Decrypt and authenticate the stream header
-		System.arraycopy(streamHeaderCiphertext, 0, streamHeaderIv, 0,
-				STREAM_HEADER_IV_LENGTH);
 		try {
-			cipher.init(false, streamHeaderKey, streamHeaderIv);
+			cipher.init(false, streamHeaderKey, streamHeaderNonce);
 			int decrypted = cipher.process(streamHeaderCiphertext,
 					STREAM_HEADER_IV_LENGTH, SecretKey.LENGTH + MAC_LENGTH,
 					streamHeaderPlaintext, 0);
diff --git a/briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java b/briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java
index 989292064752851962f90b8eab1e358ec93f7575..af5606d4407b0011a16903d1679590fc2531f751 100644
--- a/briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java
+++ b/briar-core/src/org/briarproject/crypto/StreamEncrypterFactoryImpl.java
@@ -26,25 +26,28 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory {
 		this.cipherProvider = cipherProvider;
 	}
 
+	@Override
 	public StreamEncrypter createStreamEncrypter(OutputStream out,
 			StreamContext ctx) {
 		AuthenticatedCipher cipher = cipherProvider.get();
+		long streamNumber = ctx.getStreamNumber();
 		byte[] tag = new byte[TAG_LENGTH];
-		crypto.encodeTag(tag, ctx.getTagKey(), ctx.getStreamNumber());
+		crypto.encodeTag(tag, ctx.getTagKey(), streamNumber);
 		byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH];
 		crypto.getSecureRandom().nextBytes(streamHeaderIv);
 		SecretKey frameKey = crypto.generateSecretKey();
-		return new StreamEncrypterImpl(out, cipher, tag, streamHeaderIv,
-				ctx.getHeaderKey(), frameKey);
+		return new StreamEncrypterImpl(out, cipher, streamNumber, tag,
+				streamHeaderIv, ctx.getHeaderKey(), frameKey);
 	}
 
+	@Override
 	public StreamEncrypter createInvitationStreamEncrypter(OutputStream out,
 			SecretKey headerKey) {
 		AuthenticatedCipher cipher = cipherProvider.get();
 		byte[] streamHeaderIv = new byte[STREAM_HEADER_IV_LENGTH];
 		crypto.getSecureRandom().nextBytes(streamHeaderIv);
 		SecretKey frameKey = crypto.generateSecretKey();
-		return new StreamEncrypterImpl(out, cipher, null, streamHeaderIv,
+		return new StreamEncrypterImpl(out, cipher, 0, null, streamHeaderIv,
 				headerKey, frameKey);
 	}
 }
diff --git a/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java b/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java
index 6b19fa4cbafe13019ade615438a96bdf598474bc..955bfc7d38a4135d75576edaa98cbdf212d6f81b 100644
--- a/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java
+++ b/briar-core/src/org/briarproject/crypto/StreamEncrypterImpl.java
@@ -2,6 +2,8 @@ package org.briarproject.crypto;
 
 import org.briarproject.api.crypto.SecretKey;
 import org.briarproject.api.crypto.StreamEncrypter;
+import org.briarproject.util.ByteUtils;
+import org.jetbrains.annotations.Nullable;
 
 import java.io.IOException;
 import java.io.OutputStream;
@@ -15,23 +17,28 @@ import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH
 import static org.briarproject.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH;
 import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_IV_LENGTH;
 import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_LENGTH;
+import static org.briarproject.api.transport.TransportConstants.STREAM_HEADER_NONCE_LENGTH;
+import static org.briarproject.util.ByteUtils.INT_64_BYTES;
 
 class StreamEncrypterImpl implements StreamEncrypter {
 
 	private final OutputStream out;
 	private final AuthenticatedCipher cipher;
 	private final SecretKey streamHeaderKey, frameKey;
+	private final long streamNumber;
 	private final byte[] tag, streamHeaderIv;
-	private final byte[] frameNonce, frameHeader, framePlaintext, frameCiphertext;
+	private final byte[] frameNonce, frameHeader;
+	private final byte[] framePlaintext, frameCiphertext;
 
 	private long frameNumber;
 	private boolean writeTag, writeStreamHeader;
 
 	StreamEncrypterImpl(OutputStream out, AuthenticatedCipher cipher,
-			byte[] tag, byte[] streamHeaderIv, SecretKey streamHeaderKey,
-			SecretKey frameKey) {
+			long streamNumber, @Nullable byte[] tag, byte[] streamHeaderIv,
+			SecretKey streamHeaderKey, SecretKey frameKey) {
 		this.out = out;
 		this.cipher = cipher;
+		this.streamNumber = streamNumber;
 		this.tag = tag;
 		this.streamHeaderIv = streamHeaderIv;
 		this.streamHeaderKey = streamHeaderKey;
@@ -45,6 +52,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
 		writeStreamHeader = true;
 	}
 
+	@Override
 	public void writeFrame(byte[] payload, int payloadLength,
 			int paddingLength, boolean finalFrame) throws IOException {
 		if (payloadLength + paddingLength > MAX_PAYLOAD_LENGTH)
@@ -91,18 +99,24 @@ class StreamEncrypterImpl implements StreamEncrypter {
 	}
 
 	private void writeTag() throws IOException {
+		if (tag == null) throw new IllegalStateException();
 		out.write(tag, 0, tag.length);
 		writeTag = false;
 	}
 
 	private void writeStreamHeader() throws IOException {
+		// The nonce consists of the stream number followed by the IV
+		byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
+		ByteUtils.writeUint64(streamNumber, streamHeaderNonce, 0);
+		System.arraycopy(streamHeaderIv, 0, streamHeaderNonce, INT_64_BYTES,
+				STREAM_HEADER_IV_LENGTH);
 		byte[] streamHeaderPlaintext = frameKey.getBytes();
 		byte[] streamHeaderCiphertext = new byte[STREAM_HEADER_LENGTH];
 		System.arraycopy(streamHeaderIv, 0, streamHeaderCiphertext, 0,
 				STREAM_HEADER_IV_LENGTH);
 		// Encrypt and authenticate the frame key
 		try {
-			cipher.init(true, streamHeaderKey, streamHeaderIv);
+			cipher.init(true, streamHeaderKey, streamHeaderNonce);
 			int encrypted = cipher.process(streamHeaderPlaintext, 0,
 					SecretKey.LENGTH, streamHeaderCiphertext,
 					STREAM_HEADER_IV_LENGTH);
@@ -115,6 +129,7 @@ class StreamEncrypterImpl implements StreamEncrypter {
 		writeStreamHeader = false;
 	}
 
+	@Override
 	public void flush() throws IOException {
 		// Write the tag if required
 		if (writeTag) writeTag();
diff --git a/briar-tests/src/org/briarproject/crypto/StreamDecrypterImplTest.java b/briar-tests/src/org/briarproject/crypto/StreamDecrypterImplTest.java
index e8f94711fa89bdbe7f681c746805c2515fb76083..fb60f2cb2969cdeef185f9a43cbc8d07976c76e6 100644
--- a/briar-tests/src/org/briarproject/crypto/StreamDecrypterImplTest.java
+++ b/briar-tests/src/org/briarproject/crypto/StreamDecrypterImplTest.java
@@ -22,22 +22,23 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 
 	private final AuthenticatedCipher cipher;
 	private final SecretKey streamHeaderKey, frameKey;
-	private final byte[] streamHeaderIv;
+	private final byte[] streamHeaderIv, payload;
+	private final int payloadLength = 123, paddingLength = 234;
+	private final long streamNumber = 1234;
 
 	public StreamDecrypterImplTest() {
 		cipher = new TestAuthenticatedCipher(); // Null cipher
 		streamHeaderKey = TestUtils.getSecretKey();
 		frameKey = TestUtils.getSecretKey();
 		streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH);
+		payload = TestUtils.getRandomBytes(payloadLength);
 	}
 
 	@Test
 	public void testReadValidFrames() throws Exception {
 		byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
-		int payloadLength = 123, paddingLength = 234;
 		FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
 				paddingLength);
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
 
 		byte[] frameHeader1 = new byte[FRAME_HEADER_LENGTH];
 		int payloadLength1 = 345, paddingLength1 = 456;
@@ -60,7 +61,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 
 		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
 		StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
-				streamHeaderKey);
+				streamNumber, streamHeaderKey);
 
 		// Read the first frame
 		byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -78,10 +79,9 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 	@Test(expected = IOException.class)
 	public void testTruncatedFrameThrowsException() throws Exception {
 		byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
-		int payloadLength = 123, paddingLength = 234;
 		FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
 				paddingLength);
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 		out.write(streamHeaderIv);
 		out.write(frameKey.getBytes());
@@ -93,7 +93,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 
 		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
 		StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
-				streamHeaderKey);
+				streamNumber, streamHeaderKey);
 
 		// Try to read the truncated frame
 		byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -121,7 +121,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 
 		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
 		StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
-				streamHeaderKey);
+				streamNumber, streamHeaderKey);
 
 		// Try to read the invalid frame
 		byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -131,10 +131,8 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 	@Test(expected = IOException.class)
 	public void testNonZeroPaddingThrowsException() throws Exception {
 		byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
-		int payloadLength = 123, paddingLength = 234;
 		FrameEncoder.encodeHeader(frameHeader, false, payloadLength,
 				paddingLength);
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
 		// Set one of the padding bytes non-zero
 		byte[] padding = new byte[paddingLength];
 		padding[paddingLength - 1] = 1;
@@ -150,7 +148,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 
 		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
 		StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
-				streamHeaderKey);
+				streamNumber, streamHeaderKey);
 
 		// Try to read the invalid frame
 		byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
@@ -160,10 +158,8 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 	@Test
 	public void testCannotReadBeyondFinalFrame() throws Exception {
 		byte[] frameHeader = new byte[FRAME_HEADER_LENGTH];
-		int payloadLength = 123, paddingLength = 234;
 		FrameEncoder.encodeHeader(frameHeader, true, payloadLength,
 				paddingLength);
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
 
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 		out.write(streamHeaderIv);
@@ -178,7 +174,7 @@ public class StreamDecrypterImplTest extends BriarTestCase {
 
 		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
 		StreamDecrypterImpl s = new StreamDecrypterImpl(in, cipher,
-				streamHeaderKey);
+				streamNumber, streamHeaderKey);
 
 		// Read the first frame
 		byte[] buffer = new byte[MAX_PAYLOAD_LENGTH];
diff --git a/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java b/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java
index d2d5e7eb22c1613f071b47d4cd24eace32c32965..4dccd6739fd061756ba10e6cc0a285a6afab7131 100644
--- a/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java
+++ b/briar-tests/src/org/briarproject/crypto/StreamEncrypterImplTest.java
@@ -17,7 +17,9 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 
 	private final AuthenticatedCipher cipher;
 	private final SecretKey streamHeaderKey, frameKey;
-	private final byte[] tag, streamHeaderIv;
+	private final byte[] tag, streamHeaderIv, payload;
+	private final long streamNumber = 1234;
+	private final int payloadLength = 123, paddingLength = 234;
 
 	public StreamEncrypterImplTest() {
 		cipher = new TestAuthenticatedCipher(); // Null cipher
@@ -25,15 +27,14 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 		frameKey = TestUtils.getSecretKey();
 		tag = TestUtils.getRandomBytes(TAG_LENGTH);
 		streamHeaderIv = TestUtils.getRandomBytes(STREAM_HEADER_IV_LENGTH);
+		payload = TestUtils.getRandomBytes(payloadLength);
 	}
 
 	@Test
 	public void testWriteUnpaddedNonFinalFrameWithTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, 0, false);
 
@@ -55,10 +56,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWriteUnpaddedFinalFrameWithTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, 0, true);
 
@@ -80,10 +79,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWriteUnpaddedNonFinalFrameWithoutTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, 0, false);
 
@@ -104,10 +101,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWriteUnpaddedFinalFrameWithoutTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, 0, true);
 
@@ -128,10 +123,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWritePaddedNonFinalFrameWithTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123, paddingLength = 234;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, paddingLength, false);
 
@@ -155,10 +148,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWritePaddedFinalFrameWithTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123, paddingLength = 234;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, paddingLength, true);
 
@@ -182,10 +173,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWritePaddedNonFinalFrameWithoutTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123, paddingLength = 234;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, paddingLength, false);
 
@@ -208,10 +197,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWritePaddedFinalFrameWithoutTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123, paddingLength = 234;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
 
 		s.writeFrame(payload, payloadLength, paddingLength, true);
 
@@ -234,10 +221,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testWriteTwoFramesWithTag() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
-		int payloadLength = 123, paddingLength = 234;
-		byte[] payload = TestUtils.getRandomBytes(payloadLength);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 		int payloadLength1 = 345, paddingLength1 = 456;
 		byte[] payload1 = TestUtils.getRandomBytes(payloadLength1);
 
@@ -273,8 +258,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	public void testFlushWritesTagAndStreamHeaderIfNotAlreadyWritten()
 			throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 
 		// Flush the stream once
 		s.flush();
@@ -293,8 +278,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	public void testFlushDoesNotWriteTagOrStreamHeaderIfAlreadyWritten()
 			throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, tag,
-				streamHeaderIv, streamHeaderKey, frameKey);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, tag, streamHeaderIv, streamHeaderKey, frameKey);
 
 		// Flush the stream twice
 		s.flush();
@@ -313,8 +298,8 @@ public class StreamEncrypterImplTest extends BriarTestCase {
 	@Test
 	public void testFlushDoesNotWriteTagIfNull() throws Exception {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher, null,
-				streamHeaderIv, streamHeaderKey, frameKey);
+		StreamEncrypterImpl s = new StreamEncrypterImpl(out, cipher,
+				streamNumber, null, streamHeaderIv, streamHeaderKey, frameKey);
 
 		// Flush the stream once
 		s.flush();