diff --git a/bramble-android/build.gradle b/bramble-android/build.gradle
index 9eae59ea0761f0c66bc506e716235f0ee0ca539d..4ee0d7d93225d0ee60d7d7aae64e0848c1dca179 100644
--- a/bramble-android/build.gradle
+++ b/bramble-android/build.gradle
@@ -43,6 +43,7 @@ dependencyVerification {
 			'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
 			'javax.annotation:jsr250-api:1.0:jsr250-api-1.0.jar:a1a922d0d9b6d183ed3800dfac01d1e1eb159f0e8c6f94736931c1def54a941f',
 			'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
+			'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
 			'org.bitlet:weupnp:0.1.4:weupnp-0.1.4.jar:88df7e6504929d00bdb832863761385c68ab92af945b04f0770b126270a444fb',
 			'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128-runtime.jar:e357a0f1d573c2f702a273992b1b6cb661734f66311854efb3778a888515c5b5',
 			'org.jacoco:org.jacoco.agent:0.7.4.201502262128:org.jacoco.agent-0.7.4.201502262128.jar:47b4bec6df11a1118da3953da8b9fa1e7079d6fec857faa1a3cf912e53a6fd4e',
diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java
index 9579e2e9cee8625eaa2df0503e861ca7d9e65199..67704d708f8736c4c55155b6bcafe9838d140d7e 100644
--- a/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java
+++ b/bramble-api/src/main/java/org/briarproject/bramble/api/crypto/CryptoComponent.java
@@ -20,6 +20,10 @@ public interface CryptoComponent {
 
 	KeyParser getSignatureKeyParser();
 
+	KeyPair generateEdKeyPair();
+
+	KeyParser getEdKeyParser();
+
 	KeyParser getMessageKeyParser();
 
 	/**
@@ -61,7 +65,6 @@ public interface CryptoComponent {
 	 * @param ourKeyPair our ephemeral keypair
 	 * @param alice true if ourKeyPair belongs to Alice
 	 * @return the shared secret
-	 * @throws GeneralSecurityException
 	 */
 	SecretKey deriveSharedSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
 			boolean alice) throws GeneralSecurityException;
@@ -106,7 +109,6 @@ public interface CryptoComponent {
 	 * @param ourKeyPair our ephemeral keypair
 	 * @param alice true if ourKeyPair belongs to Alice
 	 * @return the shared secret
-	 * @throws GeneralSecurityException
 	 */
 	SecretKey deriveMasterSecret(byte[] theirPublicKey, KeyPair ourKeyPair,
 			boolean alice) throws GeneralSecurityException;
@@ -130,7 +132,7 @@ public interface CryptoComponent {
 			long streamNumber);
 
 	/**
-	 * Signs the given byte[] with the given PrivateKey.
+	 * Signs the given byte[] with the given ECDSA private key.
 	 *
 	 * @param label A label specific to this signature
 	 *              to ensure that the signature cannot be repurposed
@@ -139,8 +141,17 @@ public interface CryptoComponent {
 			throws GeneralSecurityException;
 
 	/**
-	 * Verifies that the given signature is valid for the signedData
-	 * and the given publicKey.
+	 * Signs the given byte[] with the given Ed25519 private keu.
+	 *
+	 * @param label A label specific to this signature
+	 *              to ensure that the signature cannot be repurposed
+	 */
+	byte[] signEd(String label, byte[] toSign, byte[] privateKey)
+			throws GeneralSecurityException;
+
+	/**
+	 * Verifies that the given signature is valid for the signed data
+	 * and the given ECDSA public key.
 	 *
 	 * @param label A label that was specific to this signature
 	 *              to ensure that the signature cannot be repurposed
@@ -149,6 +160,17 @@ public interface CryptoComponent {
 	boolean verify(String label, byte[] signedData, byte[] publicKey,
 			byte[] signature) throws GeneralSecurityException;
 
+	/**
+	 * Verifies that the given signature is valid for the signed data
+	 * and the given Ed25519 public key.
+	 *
+	 * @param label A label that was specific to this signature
+	 *              to ensure that the signature cannot be repurposed
+	 * @return true if the signature was valid, false otherwise.
+	 */
+	boolean verifyEd(String label, byte[] signedData, byte[] publicKey,
+			byte[] signature) throws GeneralSecurityException;
+
 	/**
 	 * Returns the hash of the given inputs. The inputs are unambiguously
 	 * combined by prefixing each input with its length.
diff --git a/bramble-core/build.gradle b/bramble-core/build.gradle
index 853b760089560f17d927fd0805cb9f18dac7ec84..59361dc93eedde403d9044802caedaf426094e55 100644
--- a/bramble-core/build.gradle
+++ b/bramble-core/build.gradle
@@ -11,6 +11,7 @@ dependencies {
 	implementation 'com.madgag.spongycastle:core:1.58.0.0'
 	implementation 'com.h2database:h2:1.4.192' // This is the last version that supports Java 1.6
 	implementation 'org.bitlet:weupnp:0.1.4'
+	implementation 'net.i2p.crypto:eddsa:0.2.0'
 
 	apt 'com.google.dagger:dagger-compiler:2.0.2'
 
@@ -37,6 +38,7 @@ dependencyVerification {
 			'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
 			'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
 			'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
+			'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
 			'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
 			'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
 			'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
index d2e319c263231cd73fa8bc7c0a3e13262545070d..66f845c31ddb777b2ba8f1e92dd285dd550e61d4 100644
--- a/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/CryptoComponentImpl.java
@@ -1,5 +1,9 @@
 package org.briarproject.bramble.crypto;
 
+import net.i2p.crypto.eddsa.EdDSAPrivateKey;
+import net.i2p.crypto.eddsa.EdDSAPublicKey;
+import net.i2p.crypto.eddsa.KeyPairGenerator;
+
 import org.briarproject.bramble.api.crypto.CryptoComponent;
 import org.briarproject.bramble.api.crypto.KeyPair;
 import org.briarproject.bramble.api.crypto.KeyParser;
@@ -56,6 +60,7 @@ class CryptoComponentImpl implements CryptoComponent {
 
 	private static final int AGREEMENT_KEY_PAIR_BITS = 256;
 	private static final int SIGNATURE_KEY_PAIR_BITS = 256;
+	private static final int ED_KEY_PAIR_BITS = 256;
 	private static final int STORAGE_IV_BYTES = 24; // 196 bits
 	private static final int PBKDF_SALT_BYTES = 32; // 256 bits
 	private static final int PBKDF_TARGET_MILLIS = 500;
@@ -99,6 +104,8 @@ class CryptoComponentImpl implements CryptoComponent {
 	private final ECKeyPairGenerator signatureKeyPairGenerator;
 	private final KeyParser agreementKeyParser, signatureKeyParser;
 	private final MessageEncrypter messageEncrypter;
+	private final KeyPairGenerator edKeyPairGenerator;
+	private final KeyParser edKeyParser;
 
 	@Inject
 	CryptoComponentImpl(SecureRandomProvider secureRandomProvider) {
@@ -132,6 +139,9 @@ class CryptoComponentImpl implements CryptoComponent {
 		signatureKeyParser = new Sec1KeyParser(PARAMETERS,
 				SIGNATURE_KEY_PAIR_BITS);
 		messageEncrypter = new MessageEncrypter(secureRandom);
+		edKeyPairGenerator = new KeyPairGenerator();
+		edKeyPairGenerator.initialize(ED_KEY_PAIR_BITS, secureRandom);
+		edKeyParser = new EdKeyParser();
 	}
 
 	// Based on https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
@@ -190,6 +200,21 @@ class CryptoComponentImpl implements CryptoComponent {
 		return secret;
 	}
 
+	@Override
+	public KeyPair generateEdKeyPair() {
+		java.security.KeyPair keyPair = edKeyPairGenerator.generateKeyPair();
+		EdDSAPublicKey edPublicKey = (EdDSAPublicKey) keyPair.getPublic();
+		PublicKey publicKey = new EdPublicKey(edPublicKey.getAbyte());
+		EdDSAPrivateKey edPrivateKey = (EdDSAPrivateKey) keyPair.getPrivate();
+		PrivateKey privateKey = new EdPrivateKey(edPrivateKey.getSeed());
+		return new KeyPair(publicKey, privateKey);
+	}
+
+	@Override
+	public KeyParser getEdKeyParser() {
+		return edKeyParser;
+	}
+
 	@Override
 	public KeyPair generateAgreementKeyPair() {
 		AsymmetricCipherKeyPair keyPair =
@@ -416,19 +441,41 @@ class CryptoComponentImpl implements CryptoComponent {
 	@Override
 	public byte[] sign(String label, byte[] toSign, byte[] privateKey)
 			throws GeneralSecurityException {
-		Signature signature = new SignatureImpl(secureRandom);
-		KeyParser keyParser = getSignatureKeyParser();
+		return sign(new SignatureImpl(secureRandom), signatureKeyParser, label,
+				toSign, privateKey);
+	}
+
+	@Override
+	public byte[] signEd(String label, byte[] toSign, byte[] privateKey)
+			throws GeneralSecurityException {
+		return sign(new EdSignature(), edKeyParser, label, toSign, privateKey);
+	}
+
+	private byte[] sign(Signature sig, KeyParser keyParser, String label,
+			byte[] toSign, byte[] privateKey) throws GeneralSecurityException {
 		PrivateKey key = keyParser.parsePrivateKey(privateKey);
-		signature.initSign(key);
-		updateSignature(signature, label, toSign);
-		return signature.sign();
+		sig.initSign(key);
+		updateSignature(sig, label, toSign);
+		return sig.sign();
 	}
 
 	@Override
 	public boolean verify(String label, byte[] signedData, byte[] publicKey,
 			byte[] signature) throws GeneralSecurityException {
-		Signature sig = new SignatureImpl(secureRandom);
-		KeyParser keyParser = getSignatureKeyParser();
+		return verify(new SignatureImpl(secureRandom), signatureKeyParser,
+				label, signedData, publicKey, signature);
+	}
+
+	@Override
+	public boolean verifyEd(String label, byte[] signedData, byte[] publicKey,
+			byte[] signature) throws GeneralSecurityException {
+		return verify(new EdSignature(), edKeyParser, label, signedData,
+				publicKey, signature);
+	}
+
+	private boolean verify(Signature sig, KeyParser keyParser, String label,
+			byte[] signedData, byte[] publicKey, byte[] signature)
+			throws GeneralSecurityException {
 		PublicKey key = keyParser.parsePublicKey(publicKey);
 		sig.initVerify(key);
 		updateSignature(sig, label, signedData);
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdKeyParser.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdKeyParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e8f0844ff873fbe7de44240e69cece4f137aac5
--- /dev/null
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdKeyParser.java
@@ -0,0 +1,26 @@
+package org.briarproject.bramble.crypto;
+
+import org.briarproject.bramble.api.crypto.KeyParser;
+import org.briarproject.bramble.api.crypto.PrivateKey;
+import org.briarproject.bramble.api.crypto.PublicKey;
+import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+
+import java.security.GeneralSecurityException;
+
+@NotNullByDefault
+class EdKeyParser implements KeyParser {
+
+	@Override
+	public PublicKey parsePublicKey(byte[] encodedKey)
+			throws GeneralSecurityException {
+		if (encodedKey.length != 32) throw new GeneralSecurityException();
+		return new EdPublicKey(encodedKey);
+	}
+
+	@Override
+	public PrivateKey parsePrivateKey(byte[] encodedKey)
+			throws GeneralSecurityException {
+		if (encodedKey.length != 32) throw new GeneralSecurityException();
+		return new EdPrivateKey(encodedKey);
+	}
+}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdPrivateKey.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdPrivateKey.java
new file mode 100644
index 0000000000000000000000000000000000000000..c58912db188e302ff2cce455333d6ce048b621f1
--- /dev/null
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdPrivateKey.java
@@ -0,0 +1,18 @@
+package org.briarproject.bramble.crypto;
+
+import org.briarproject.bramble.api.Bytes;
+import org.briarproject.bramble.api.crypto.PrivateKey;
+import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+
+@NotNullByDefault
+class EdPrivateKey extends Bytes implements PrivateKey {
+
+	EdPrivateKey(byte[] bytes) {
+		super(bytes);
+	}
+
+	@Override
+	public byte[] getEncoded() {
+		return getBytes();
+	}
+}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdPublicKey.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdPublicKey.java
new file mode 100644
index 0000000000000000000000000000000000000000..862011f7e6fb775429f1240ac41e74ed5b2ad9b0
--- /dev/null
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdPublicKey.java
@@ -0,0 +1,18 @@
+package org.briarproject.bramble.crypto;
+
+import org.briarproject.bramble.api.Bytes;
+import org.briarproject.bramble.api.crypto.PublicKey;
+import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+
+@NotNullByDefault
+class EdPublicKey extends Bytes implements PublicKey {
+
+	EdPublicKey(byte[] bytes) {
+		super(bytes);
+	}
+
+	@Override
+	public byte[] getEncoded() {
+		return getBytes();
+	}
+}
diff --git a/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdSignature.java b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdSignature.java
new file mode 100644
index 0000000000000000000000000000000000000000..7d3a658e61d639ee8d8b9a9edd50827aba73e1d4
--- /dev/null
+++ b/bramble-core/src/main/java/org/briarproject/bramble/crypto/EdSignature.java
@@ -0,0 +1,103 @@
+package org.briarproject.bramble.crypto;
+
+import net.i2p.crypto.eddsa.EdDSAPrivateKey;
+import net.i2p.crypto.eddsa.EdDSAPublicKey;
+import net.i2p.crypto.eddsa.EdDSASecurityProvider;
+import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec;
+import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
+import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
+import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
+
+import org.briarproject.bramble.api.crypto.PrivateKey;
+import org.briarproject.bramble.api.crypto.PublicKey;
+import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
+
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.SignatureException;
+
+import static net.i2p.crypto.eddsa.EdDSAEngine.SIGNATURE_ALGORITHM;
+
+@NotNullByDefault
+class EdSignature implements Signature {
+
+	private static final Provider PROVIDER = new EdDSASecurityProvider();
+
+	private static final EdDSANamedCurveSpec CURVE_SPEC =
+			EdDSANamedCurveTable.getByName("Ed25519");
+
+	private final java.security.Signature signature;
+
+	EdSignature() {
+		try {
+			signature = java.security.Signature
+					.getInstance(SIGNATURE_ALGORITHM, PROVIDER);
+		} catch (NoSuchAlgorithmException e) {
+			throw new AssertionError(e);
+		}
+	}
+
+	@Override
+	public void initSign(PrivateKey k) throws GeneralSecurityException {
+		if (!(k instanceof EdPrivateKey))
+			throw new IllegalArgumentException();
+		EdDSAPrivateKey privateKey = new EdDSAPrivateKey(
+				new EdDSAPrivateKeySpec(k.getEncoded(), CURVE_SPEC));
+		signature.initSign(privateKey);
+	}
+
+	@Override
+	public void initVerify(PublicKey k) throws GeneralSecurityException {
+		if (!(k instanceof EdPublicKey))
+			throw new IllegalArgumentException();
+		EdDSAPublicKey publicKey = new EdDSAPublicKey(
+				new EdDSAPublicKeySpec(k.getEncoded(), CURVE_SPEC));
+		signature.initVerify(publicKey);
+	}
+
+	@Override
+	public void update(byte b) {
+		try {
+			signature.update(b);
+		} catch (SignatureException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public void update(byte[] b) {
+		try {
+			signature.update(b);
+		} catch (SignatureException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public void update(byte[] b, int off, int len) {
+		try {
+			signature.update(b, off, len);
+		} catch (SignatureException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public byte[] sign() {
+		try {
+			return signature.sign();
+		} catch (SignatureException e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	public boolean verify(byte[] sig) {
+		try {
+			return signature.verify(sig);
+		} catch (SignatureException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/EcdsaSignatureTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/EcdsaSignatureTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d1c960cd1d9279cbd577e9b22141a09b4a33f14
--- /dev/null
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/EcdsaSignatureTest.java
@@ -0,0 +1,25 @@
+package org.briarproject.bramble.crypto;
+
+import org.briarproject.bramble.api.crypto.KeyPair;
+
+import java.security.GeneralSecurityException;
+
+public class EcdsaSignatureTest extends SignatureTest {
+
+	@Override
+	protected KeyPair generateKeyPair() {
+		return crypto.generateSignatureKeyPair();
+	}
+
+	@Override
+	protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
+			throws GeneralSecurityException {
+		return crypto.sign(label, toSign, privateKey);
+	}
+
+	@Override
+	protected boolean verify(String label, byte[] signedData, byte[] publicKey,
+			byte[] signature) throws GeneralSecurityException {
+		return crypto.verify(label, signedData, publicKey, signature);
+	}
+}
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/EdSignatureTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/EdSignatureTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5d57f2dffdf0c4a5eea86b818db6969baa41af9b
--- /dev/null
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/EdSignatureTest.java
@@ -0,0 +1,25 @@
+package org.briarproject.bramble.crypto;
+
+import org.briarproject.bramble.api.crypto.KeyPair;
+
+import java.security.GeneralSecurityException;
+
+public class EdSignatureTest extends SignatureTest {
+
+	@Override
+	protected KeyPair generateKeyPair() {
+		return crypto.generateEdKeyPair();
+	}
+
+	@Override
+	protected byte[] sign(String label, byte[] toSign, byte[] privateKey)
+			throws GeneralSecurityException {
+		return crypto.signEd(label, toSign, privateKey);
+	}
+
+	@Override
+	protected boolean verify(String label, byte[] signedData, byte[] publicKey,
+			byte[] signature) throws GeneralSecurityException {
+		return crypto.verifyEd(label, signedData, publicKey, signature);
+	}
+}
\ No newline at end of file
diff --git a/bramble-core/src/test/java/org/briarproject/bramble/crypto/SignatureTest.java b/bramble-core/src/test/java/org/briarproject/bramble/crypto/SignatureTest.java
index 4bf6017a8b9babf5d3307d7a7d9aa3babfeed1cf..1abe4a71a56ad55252e994daa1a60154d7ace798 100644
--- a/bramble-core/src/test/java/org/briarproject/bramble/crypto/SignatureTest.java
+++ b/bramble-core/src/test/java/org/briarproject/bramble/crypto/SignatureTest.java
@@ -8,23 +8,32 @@ import org.briarproject.bramble.test.TestUtils;
 import org.briarproject.bramble.util.StringUtils;
 import org.junit.Test;
 
+import java.security.GeneralSecurityException;
 import java.util.Arrays;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-public class SignatureTest extends BrambleTestCase {
+public abstract class SignatureTest extends BrambleTestCase {
 
-	private final CryptoComponent crypto;
+	protected final CryptoComponent crypto;
 
 	private final byte[] publicKey, privateKey;
 	private final String label = StringUtils.getRandomString(42);
 	private final byte[] inputBytes = TestUtils.getRandomBytes(123);
 
-	public SignatureTest() {
+	protected abstract KeyPair generateKeyPair();
+
+	protected abstract byte[] sign(String label, byte[] toSign,
+			byte[] privateKey) throws GeneralSecurityException;
+
+	protected abstract boolean verify(String label, byte[] signedData,
+			byte[] publicKey, byte[] signature) throws GeneralSecurityException;
+
+	SignatureTest() {
 		crypto = new CryptoComponentImpl(new TestSecureRandomProvider());
-		KeyPair k = crypto.generateSignatureKeyPair();
+		KeyPair k = generateKeyPair();
 		publicKey = k.getPublic().getEncoded();
 		privateKey = k.getPrivate().getEncoded();
 	}
@@ -33,19 +42,19 @@ public class SignatureTest extends BrambleTestCase {
 	public void testIdenticalKeysAndInputsProduceIdenticalSignatures()
 			throws Exception {
 		// Calculate the Signature twice - the results should be identical
-		byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
-		byte[] sig2 = crypto.sign(label, inputBytes, privateKey);
+		byte[] sig1 = sign(label, inputBytes, privateKey);
+		byte[] sig2 = sign(label, inputBytes, privateKey);
 		assertArrayEquals(sig1, sig2);
 	}
 
 	@Test
 	public void testDifferentKeysProduceDifferentSignatures() throws Exception {
 		// Generate second private key
-		KeyPair k2 = crypto.generateSignatureKeyPair();
+		KeyPair k2 = generateKeyPair();
 		byte[] privateKey2 = k2.getPrivate().getEncoded();
 		// Calculate the signature with each key
-		byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
-		byte[] sig2 = crypto.sign(label, inputBytes, privateKey2);
+		byte[] sig1 = sign(label, inputBytes, privateKey);
+		byte[] sig2 = sign(label, inputBytes, privateKey2);
 		assertFalse(Arrays.equals(sig1, sig2));
 	}
 
@@ -56,8 +65,8 @@ public class SignatureTest extends BrambleTestCase {
 		byte[] inputBytes2 = TestUtils.getRandomBytes(123);
 		// Calculate the signature with different inputs
 		// the results should be different
-		byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
-		byte[] sig2 = crypto.sign(label, inputBytes2, privateKey);
+		byte[] sig1 = sign(label, inputBytes, privateKey);
+		byte[] sig2 = sign(label, inputBytes2, privateKey);
 		assertFalse(Arrays.equals(sig1, sig2));
 	}
 
@@ -68,25 +77,25 @@ public class SignatureTest extends BrambleTestCase {
 		String label2 = StringUtils.getRandomString(42);
 		// Calculate the signature with different inputs
 		// the results should be different
-		byte[] sig1 = crypto.sign(label, inputBytes, privateKey);
-		byte[] sig2 = crypto.sign(label2, inputBytes, privateKey);
+		byte[] sig1 = sign(label, inputBytes, privateKey);
+		byte[] sig2 = sign(label2, inputBytes, privateKey);
 		assertFalse(Arrays.equals(sig1, sig2));
 	}
 
 	@Test
 	public void testSignatureVerification() throws Exception {
-		byte[] sig = crypto.sign(label, inputBytes, privateKey);
-		assertTrue(crypto.verify(label, inputBytes, publicKey, sig));
+		byte[] sig = sign(label, inputBytes, privateKey);
+		assertTrue(verify(label, inputBytes, publicKey, sig));
 	}
 
 	@Test
 	public void testDifferentKeyFailsVerification() throws Exception {
 		// Generate second private key
-		KeyPair k2 = crypto.generateSignatureKeyPair();
+		KeyPair k2 = generateKeyPair();
 		byte[] privateKey2 = k2.getPrivate().getEncoded();
 		// calculate the signature with different key, should fail to verify
-		byte[] sig = crypto.sign(label, inputBytes, privateKey2);
-		assertFalse(crypto.verify(label, inputBytes, publicKey, sig));
+		byte[] sig = sign(label, inputBytes, privateKey2);
+		assertFalse(verify(label, inputBytes, publicKey, sig));
 	}
 
 	@Test
@@ -94,8 +103,8 @@ public class SignatureTest extends BrambleTestCase {
 		// Generate a second input
 		byte[] inputBytes2 = TestUtils.getRandomBytes(123);
 		// calculate the signature with different input, should fail to verify
-		byte[] sig = crypto.sign(label, inputBytes, privateKey);
-		assertFalse(crypto.verify(label, inputBytes2, publicKey, sig));
+		byte[] sig = sign(label, inputBytes, privateKey);
+		assertFalse(verify(label, inputBytes2, publicKey, sig));
 	}
 
 	@Test
@@ -103,8 +112,8 @@ public class SignatureTest extends BrambleTestCase {
 		// Generate a second label
 		String label2 = StringUtils.getRandomString(42);
 		// calculate the signature with different label, should fail to verify
-		byte[] sig = crypto.sign(label, inputBytes, privateKey);
-		assertFalse(crypto.verify(label2, inputBytes, publicKey, sig));
+		byte[] sig = sign(label, inputBytes, privateKey);
+		assertFalse(verify(label2, inputBytes, publicKey, sig));
 	}
 
 }
diff --git a/bramble-j2se/build.gradle b/bramble-j2se/build.gradle
index 7294bff5c5f1104715a19e97ea2bfbc2fbd44fc9..2ba13659e0b77d00f69b8271be3a72e1f94cc0ed 100644
--- a/bramble-j2se/build.gradle
+++ b/bramble-j2se/build.gradle
@@ -36,6 +36,7 @@ dependencyVerification {
 			'com.madgag.spongycastle:core:1.58.0.0:core-1.58.0.0.jar:199617dd5698c5a9312b898c0a4cec7ce9dd8649d07f65d91629f58229d72728',
 			'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
 			'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
+			'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
 			'net.java.dev.jna:jna-platform:4.4.0:jna-platform-4.4.0.jar:e9dda9e884fc107eb6367710540789a12dfa8ad28be9326b22ca6e352e325499',
 			'net.java.dev.jna:jna:4.4.0:jna-4.4.0.jar:c4dadeeecaa90c8847902082aee5eb107fcf59c5d0e63a17fcaf273c0e2d2bd1',
 			'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
diff --git a/briar-android/build.gradle b/briar-android/build.gradle
index d2601109a2291ea85279e929e41c68a22ed4d00b..5f25795c2d940195d2d54c31f9fd3adbc42b9a83 100644
--- a/briar-android/build.gradle
+++ b/briar-android/build.gradle
@@ -99,6 +99,7 @@ dependencyVerification {
 			'nekohtml:xercesMinimal:1.9.6.2:xercesMinimal-1.9.6.2.jar:95b8b357d19f63797dd7d67622fd3f18374d64acbc6584faba1c7759a31e8438',
 			'net.bytebuddy:byte-buddy-agent:1.6.14:byte-buddy-agent-1.6.14.jar:c141a2d6809c3eeff4a43d25992826abccebdd4b793af3e7a5f346e88ae73a33',
 			'net.bytebuddy:byte-buddy:1.6.14:byte-buddy-1.6.14.jar:917758b3c651e278a15a029ba1d42dbf802d8b0e1fe2aa4b81c5750c64f461c1',
+			'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
 			'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
 			'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
 			'org.apache.maven.wagon:wagon-file:1.0-beta-6:wagon-file-1.0-beta-6.jar:7298feeb36ff14dd933c38e62585fb9973fea32fb3c4bc5379428cb1aac5dd3c',
diff --git a/briar-core/build.gradle b/briar-core/build.gradle
index 2965e48d44a94b6ffe1e6639aed31d9b6c520e1c..8f03ea2bac12120d97d8c814bc6ce86e66b20a93 100644
--- a/briar-core/build.gradle
+++ b/briar-core/build.gradle
@@ -45,6 +45,7 @@ dependencyVerification {
 			'com.squareup.okio:okio:1.13.0:okio-1.13.0.jar:734269c3ebc5090e3b23566db558f421f0b4027277c79ad5d176b8ec168bb850',
 			'javax.inject:javax.inject:1:javax.inject-1.jar:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
 			'junit:junit:4.12:junit-4.12.jar:59721f0805e223d84b90677887d9ff567dc534d7c502ca903c0c2b17f05c116a',
+			'net.i2p.crypto:eddsa:0.2.0:eddsa-0.2.0.jar:a7cb1b85c16e2f0730b9204106929a1d9aaae1df728adc7041a8b8b605692140',
 			'net.jodah:concurrentunit:0.4.2:concurrentunit-0.4.2.jar:5583078e1acf91734939e985bc9e7ee947b0e93a8eef679da6bb07bbeb47ced3',
 			'org.apache.ant:ant-launcher:1.9.4:ant-launcher-1.9.4.jar:7bccea20b41801ca17bcbc909a78c835d0f443f12d639c77bd6ae3d05861608d',
 			'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',