diff --git a/api/net/sf/briar/api/transport/PacketReader.java b/api/net/sf/briar/api/transport/PacketReader.java
index 7094bb025f5b706d12a855c485148b1c1918d350..0dde50d3279ed07afc358e9438c94adf25c9a4e4 100644
--- a/api/net/sf/briar/api/transport/PacketReader.java
+++ b/api/net/sf/briar/api/transport/PacketReader.java
@@ -10,8 +10,8 @@ import net.sf.briar.api.protocol.SubscriptionUpdate;
 import net.sf.briar.api.protocol.TransportUpdate;
 
 /**
- * Reads unencrypted packets from an underlying input stream and authenticates
- * them.
+ * Reads encrypted packets from an underlying input stream, decrypts and
+ * authenticates them.
  */
 public interface PacketReader {
 
diff --git a/components/net/sf/briar/crypto/SharedSecret.java b/components/net/sf/briar/crypto/SharedSecret.java
index 5c144dcc56e61ffeb2baa84c11887a8384441e23..2240164517d7f786e648fe3f0bfc6d544faef931 100644
--- a/components/net/sf/briar/crypto/SharedSecret.java
+++ b/components/net/sf/briar/crypto/SharedSecret.java
@@ -16,7 +16,7 @@ import javax.crypto.spec.IvParameterSpec;
  */
 class SharedSecret {
 
-	private static final int IV_BYTES = 16;
+	static final int IV_BYTES = 16;
 
 	private final IvParameterSpec iv;
 	private final boolean alice;
diff --git a/components/net/sf/briar/transport/ConnectionRecogniserImpl.java b/components/net/sf/briar/transport/ConnectionRecogniserImpl.java
index 6779c6ad720da280cd15720db6dee7d55b172280..605a0ffbe1d45fe578317e05c33fc6d5d9523c7d 100644
--- a/components/net/sf/briar/transport/ConnectionRecogniserImpl.java
+++ b/components/net/sf/briar/transport/ConnectionRecogniserImpl.java
@@ -92,7 +92,8 @@ DatabaseListener {
 
 	public synchronized ContactId acceptConnection(byte[] tag)
 	throws DbException {
-		if(tag.length != 16) throw new IllegalArgumentException();
+		if(tag.length != Constants.TAG_BYTES)
+			throw new IllegalArgumentException();
 		if(!initialised) initialise();
 		Bytes b = new Bytes(tag);
 		ContactId contactId = tagToContact.remove(b);
diff --git a/components/net/sf/briar/transport/Constants.java b/components/net/sf/briar/transport/Constants.java
index 07c96eaa065c3032cb01f007fb2a4d0d882acf80..07d8a1fd2320460e33efc1dfc7d3445de864c350 100644
--- a/components/net/sf/briar/transport/Constants.java
+++ b/components/net/sf/briar/transport/Constants.java
@@ -2,7 +2,7 @@ package net.sf.briar.transport;
 
 interface Constants {
 
+	static final int TAG_BYTES = 16;
 	static final int MAX_16_BIT_UNSIGNED = 65535; // 2^16 - 1
 	static final long MAX_32_BIT_UNSIGNED = 4294967295L; // 2^32 - 1
-
 }
diff --git a/components/net/sf/briar/transport/PacketEncrypter.java b/components/net/sf/briar/transport/PacketEncrypter.java
index 17543dacee3106ae7274cf82f19641ce1b8cc111..7652753b2611fbe74e58ba66ac96fbb95b3085af 100644
--- a/components/net/sf/briar/transport/PacketEncrypter.java
+++ b/components/net/sf/briar/transport/PacketEncrypter.java
@@ -5,9 +5,12 @@ import java.io.OutputStream;
 
 interface PacketEncrypter {
 
+	/** Returns the output stream to which packets should be written. */
 	OutputStream getOutputStream();
 
+	/** Encrypts the given tag and writes it to the underlying output stream. */
 	void writeTag(byte[] tag) throws IOException;
 
+	/** Finishes writing the current packet. */
 	void finishPacket() throws IOException;
 }
diff --git a/components/net/sf/briar/transport/PacketEncrypterImpl.java b/components/net/sf/briar/transport/PacketEncrypterImpl.java
index ebde4771306e38d93f43536733279cdfd3cbc33f..69ca0c9ca3aa60d608f4caaa4ce1d0af22c3ab16 100644
--- a/components/net/sf/briar/transport/PacketEncrypterImpl.java
+++ b/components/net/sf/briar/transport/PacketEncrypterImpl.java
@@ -15,14 +15,12 @@ import javax.crypto.spec.IvParameterSpec;
 class PacketEncrypterImpl extends FilterOutputStream
 implements PacketEncrypter {
 
-	private final OutputStream out;
 	private final Cipher tagCipher, packetCipher;
 	private final SecretKey packetKey;
 
 	PacketEncrypterImpl(OutputStream out, Cipher tagCipher,
 			Cipher packetCipher, SecretKey tagKey, SecretKey packetKey) {
 		super(out);
-		this.out = out;
 		this.tagCipher = tagCipher;
 		this.packetCipher = packetCipher;
 		this.packetKey = packetKey;
@@ -31,7 +29,7 @@ implements PacketEncrypter {
 		} catch(InvalidKeyException e) {
 			throw new IllegalArgumentException(e);
 		}
-		if(tagCipher.getOutputSize(16) != 16)
+		if(tagCipher.getOutputSize(Constants.TAG_BYTES) != Constants.TAG_BYTES)
 			throw new IllegalArgumentException();
 	}
 
@@ -40,7 +38,8 @@ implements PacketEncrypter {
 	}
 
 	public void writeTag(byte[] tag) throws IOException {
-		if(tag.length != 16) throw new IllegalArgumentException();
+		if(tag.length != Constants.TAG_BYTES)
+			throw new IllegalArgumentException();
 		IvParameterSpec iv = new IvParameterSpec(tag);
 		try {
 			out.write(tagCipher.doFinal(tag));
diff --git a/components/net/sf/briar/transport/TagEncoder.java b/components/net/sf/briar/transport/TagEncoder.java
index aead6debbf2de9d251b8091ba03d4822e9c3f1f1..98c0b1fe87924885742e691de34910a6b81218f7 100644
--- a/components/net/sf/briar/transport/TagEncoder.java
+++ b/components/net/sf/briar/transport/TagEncoder.java
@@ -4,7 +4,7 @@ public class TagEncoder {
 
 	static byte[] encodeTag(int transportIdentifier, long connectionNumber,
 			long packetNumber) {
-		byte[] tag = new byte[16];
+		byte[] tag = new byte[Constants.TAG_BYTES];
 		// Encode the transport identifier as an unsigned 16-bit integer
 		writeUint16(transportIdentifier, tag, 2);
 		// Encode the connection number as an unsigned 32-bit integer
diff --git a/test/net/sf/briar/crypto/SharedSecretTest.java b/test/net/sf/briar/crypto/SharedSecretTest.java
index ebaa879976deaeaeac323ff78ab2968718456e45..7de0c80b35494ee5efeeb56446795961914ea53b 100644
--- a/test/net/sf/briar/crypto/SharedSecretTest.java
+++ b/test/net/sf/briar/crypto/SharedSecretTest.java
@@ -14,22 +14,22 @@ public class SharedSecretTest extends TestCase {
 		Random random = new Random();
 		byte[] secret = new byte[40];
 		random.nextBytes(secret);
-		secret[16] = (byte) 0;
+		secret[SharedSecret.IV_BYTES] = (byte) 0;
 		SharedSecret s = new SharedSecret(secret);
 		assertTrue(Arrays.equals(secret, s.getBytes()));
-		secret[16] = (byte) 1;
+		secret[SharedSecret.IV_BYTES] = (byte) 1;
 		s = new SharedSecret(secret);
 		assertTrue(Arrays.equals(secret, s.getBytes()));
 		// The Alice flag must be either 0 or 1
-		secret[16] = (byte) 2;
+		secret[SharedSecret.IV_BYTES] = (byte) 2;
 		try {
 			s = new SharedSecret(secret);
 			fail();
 		} catch(IllegalArgumentException expected) {}
-		// The secret must be at least 18 bytes long
-		secret = new byte[17];
+		// The ciphertext must be at least 1 byte long
+		secret = new byte[SharedSecret.IV_BYTES + 1];
 		random.nextBytes(secret);
-		secret[16] = (byte) 0;
+		secret[SharedSecret.IV_BYTES] = (byte) 0;
 		try {
 			s = new SharedSecret(secret);
 			fail();
diff --git a/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java b/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java
index 7ec47deb53e50043c37a41a811f03538b7ef14d5..948a7872ae05661597d8fc581ba5fcc5fa7fb013 100644
--- a/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java
+++ b/test/net/sf/briar/transport/ConnectionRecogniserImplTest.java
@@ -53,7 +53,7 @@ public class ConnectionRecogniserImplTest extends TestCase {
 		}});
 		final ConnectionRecogniserImpl c =
 			new ConnectionRecogniserImpl(transportId, crypto, db);
-		assertNull(c.acceptConnection(new byte[16]));
+		assertNull(c.acceptConnection(new byte[Constants.TAG_BYTES]));
 		context.assertIsSatisfied();
 	}
 
diff --git a/test/net/sf/briar/transport/PacketEncrypterImplTest.java b/test/net/sf/briar/transport/PacketEncrypterImplTest.java
index 8cd64954eb4427c93bb80b50d99ae10f9f7cb3d0..2132223f2cf918d7384c35bebb6b7da720a74a5f 100644
--- a/test/net/sf/briar/transport/PacketEncrypterImplTest.java
+++ b/test/net/sf/briar/transport/PacketEncrypterImplTest.java
@@ -36,7 +36,7 @@ public class PacketEncrypterImplTest extends TestCase {
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
 		PacketEncrypter p = new PacketEncrypterImpl(out, tagCipher,
 				packetCipher, tagKey, packetKey);
-		p.writeTag(new byte[16]);
+		p.writeTag(new byte[Constants.TAG_BYTES]);
 		p.getOutputStream().write((byte) 0);
 		p.finishPacket();
 		assertEquals(17, out.toByteArray().length);
@@ -44,7 +44,7 @@ public class PacketEncrypterImplTest extends TestCase {
 
 	@Test
 	public void testEncryption() throws Exception {
-		byte[] tag = new byte[16];
+		byte[] tag = new byte[Constants.TAG_BYTES];
 		byte[] packet = new byte[123];
 		// Calculate the expected encrypted tag
 		tagCipher.init(Cipher.ENCRYPT_MODE, tagKey);
@@ -63,14 +63,15 @@ public class PacketEncrypterImplTest extends TestCase {
 		p.getOutputStream().write(packet);
 		p.finishPacket();
 		byte[] ciphertext = out.toByteArray();
-		assertEquals(16 + packet.length, ciphertext.length);
+		assertEquals(Constants.TAG_BYTES + packet.length, ciphertext.length);
 		// Check the tag
-		byte[] actualTag = new byte[16];
-		System.arraycopy(ciphertext, 0, actualTag, 0, 16);
+		byte[] actualTag = new byte[Constants.TAG_BYTES];
+		System.arraycopy(ciphertext, 0, actualTag, 0, Constants.TAG_BYTES);
 		assertTrue(Arrays.equals(expectedTag, actualTag));
 		// Check the packet
 		byte[] actualPacket = new byte[packet.length];
-		System.arraycopy(ciphertext, 16, actualPacket, 0, actualPacket.length);
+		System.arraycopy(ciphertext, Constants.TAG_BYTES, actualPacket, 0,
+				actualPacket.length);
 		assertTrue(Arrays.equals(expectedPacket, actualPacket));
 	}
 }
diff --git a/test/net/sf/briar/transport/PacketWriterImplTest.java b/test/net/sf/briar/transport/PacketWriterImplTest.java
index 94783c7a28cd87bb7ebe2c2ef5b5ab038f568c68..c79234b3647a2a6a7d732c5fc3522a175619bbd2 100644
--- a/test/net/sf/briar/transport/PacketWriterImplTest.java
+++ b/test/net/sf/briar/transport/PacketWriterImplTest.java
@@ -36,8 +36,9 @@ public class PacketWriterImplTest extends TestCase {
 		PacketEncrypter e = new NullPacketEncrypter(out);
 		PacketWriter p = new PacketWriterImpl(e, mac, 0, 0L);
 		p.getOutputStream().write(0);
-		// There should be 16 zero bytes for the tag, 1 for the byte written
-		assertTrue(Arrays.equals(new byte[17], out.toByteArray()));
+		// There should be TAG_BYTES bytes for the tag, 1 byte for the write
+		assertTrue(Arrays.equals(new byte[Constants.TAG_BYTES + 1],
+				out.toByteArray()));
 	}
 
 	@Test
@@ -93,6 +94,7 @@ public class PacketWriterImplTest extends TestCase {
 				+ "00000000" // 32 bits for the packet number
 				+ "00000000" // 32 bits for the block number
 		);
+		assertEquals(Constants.TAG_BYTES, expectedTag.length);
 		byte[] expectedTag1 = StringUtils.fromHexString(
 				"0000" // 16 bits reserved
 				+ "F00D" // 16 bits for the transport ID
@@ -100,6 +102,7 @@ public class PacketWriterImplTest extends TestCase {
 				+ "00000001" // 32 bits for the packet number
 				+ "00000000" // 32 bits for the block number
 		);
+		assertEquals(Constants.TAG_BYTES, expectedTag1.length);
 		// Calculate what the MAC on the first packet should be
 		mac.update(expectedTag);
 		mac.update((byte) 0);
@@ -119,24 +122,27 @@ public class PacketWriterImplTest extends TestCase {
 		p.getOutputStream().write(0);
 		p.nextPacket();
 		byte[] written = out.toByteArray();
-		assertEquals(17 + expectedMac.length + 17 + expectedMac1.length,
+		assertEquals(Constants.TAG_BYTES + 1 + expectedMac.length
+				+ Constants.TAG_BYTES + 1 + expectedMac1.length,
 				written.length);
 		// Check the first packet's tag
-		byte[] actualTag = new byte[16];
-		System.arraycopy(written, 0, actualTag, 0, 16);
+		byte[] actualTag = new byte[Constants.TAG_BYTES];
+		System.arraycopy(written, 0, actualTag, 0, Constants.TAG_BYTES);
 		assertTrue(Arrays.equals(expectedTag, actualTag));
 		// Check the first packet's MAC
 		byte[] actualMac = new byte[expectedMac.length];
-		System.arraycopy(written, 17, actualMac, 0, actualMac.length);
+		System.arraycopy(written, Constants.TAG_BYTES + 1, actualMac, 0,
+				actualMac.length);
 		assertTrue(Arrays.equals(expectedMac, actualMac));
 		// Check the second packet's tag
-		byte[] actualTag1 = new byte[16];
-		System.arraycopy(written, 17 + expectedMac.length, actualTag1, 0, 16);
+		byte[] actualTag1 = new byte[Constants.TAG_BYTES];
+		System.arraycopy(written, Constants.TAG_BYTES + 1 + expectedMac.length,
+				actualTag1, 0, Constants.TAG_BYTES);
 		assertTrue(Arrays.equals(expectedTag1, actualTag1));
 		// Check the second packet's MAC
 		byte[] actualMac1 = new byte[expectedMac1.length];
-		System.arraycopy(written, 17 + expectedMac.length + 17, actualMac1, 0,
-				actualMac1.length);
+		System.arraycopy(written, Constants.TAG_BYTES + 1 + expectedMac.length
+				+ Constants.TAG_BYTES + 1, actualMac1, 0, actualMac1.length);
 		assertTrue(Arrays.equals(expectedMac1, actualMac1));
 	}