Use Curve25519 for key agreement.

This commit is contained in:
akwizgran
2018-02-02 17:52:18 +00:00
parent ad241a14e3
commit 56a5b8df87
11 changed files with 120 additions and 88 deletions

View File

@@ -13,11 +13,11 @@ import org.spongycastle.crypto.params.ECPrivateKeyParameters;
import org.spongycastle.crypto.params.ECPublicKeyParameters;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint;
import org.spongycastle.math.ec.MontgomeryLadderMultiplier;
import java.math.BigInteger;
import java.security.SecureRandom;
import static org.briarproject.bramble.crypto.EllipticCurveConstants.PARAMETERS;
import static org.junit.Assert.assertEquals;
public class EllipticCurveMultiplicationTest extends BrambleTestCase {
@@ -31,15 +31,11 @@ public class EllipticCurveMultiplicationTest extends BrambleTestCase {
ECPoint defaultG = defaultX9Parameters.getG();
BigInteger defaultN = defaultX9Parameters.getN();
BigInteger defaultH = defaultX9Parameters.getH();
// Check that the default parameters are equal to our parameters
assertEquals(PARAMETERS.getCurve(), defaultCurve);
assertEquals(PARAMETERS.getG(), defaultG);
assertEquals(PARAMETERS.getN(), defaultN);
assertEquals(PARAMETERS.getH(), defaultH);
// ECDomainParameters doesn't have an equals() method, but it's just a
// container for the parameters
ECDomainParameters defaultParameters = new ECDomainParameters(
defaultCurve, defaultG, defaultN, defaultH);
// Instantiate an implementation using the Montgomery ladder multiplier
ECDomainParameters montgomeryParameters =
constantTime(defaultParameters);
// Generate two key pairs with each set of parameters, using the same
// deterministic PRNG for both sets of parameters
byte[] seed = new byte[32];
@@ -47,7 +43,7 @@ public class EllipticCurveMultiplicationTest extends BrambleTestCase {
// Montgomery ladder multiplier
SecureRandom random = new PseudoSecureRandom(seed);
ECKeyGenerationParameters montgomeryGeneratorParams =
new ECKeyGenerationParameters(PARAMETERS, random);
new ECKeyGenerationParameters(montgomeryParameters, random);
ECKeyPairGenerator montgomeryGenerator = new ECKeyPairGenerator();
montgomeryGenerator.init(montgomeryGeneratorParams);
AsymmetricCipherKeyPair montgomeryKeyPair1 =
@@ -107,4 +103,13 @@ public class EllipticCurveMultiplicationTest extends BrambleTestCase {
assertEquals(sharedSecretMontgomeryMontgomery,
sharedSecretDefaultDefault);
}
private static ECDomainParameters constantTime(ECDomainParameters in) {
ECCurve curve = in.getCurve().configure().setMultiplier(
new MontgomeryLadderMultiplier()).create();
BigInteger x = in.getG().getAffineXCoord().toBigInteger();
BigInteger y = in.getG().getAffineYCoord().toBigInteger();
ECPoint g = curve.createPoint(x, y);
return new ECDomainParameters(curve, g, in.getN(), in.getH());
}
}

View File

@@ -38,7 +38,6 @@ import java.util.Collections;
import java.util.List;
import static net.i2p.crypto.eddsa.EdDSAEngine.SIGNATURE_ALGORITHM;
import static org.briarproject.bramble.crypto.EllipticCurveConstants.PARAMETERS;
// Not a JUnit test
public class EllipticCurvePerformanceTest {
@@ -65,7 +64,6 @@ public class EllipticCurvePerformanceTest {
runTest(name + " default", params);
runTest(name + " constant", constantTime(params));
}
runTest("ours", PARAMETERS);
runCurve25519Test();
runEd25519Test();
}

View File

@@ -2,11 +2,13 @@ package org.briarproject.bramble.crypto;
import org.briarproject.bramble.api.crypto.CryptoComponent;
import org.briarproject.bramble.api.crypto.KeyPair;
import org.briarproject.bramble.api.crypto.PublicKey;
import org.briarproject.bramble.api.crypto.SecretKey;
import org.briarproject.bramble.test.BrambleTestCase;
import org.briarproject.bramble.test.TestSecureRandomProvider;
import org.junit.Test;
import java.security.GeneralSecurityException;
import java.util.Random;
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL;
@@ -15,20 +17,33 @@ import static org.junit.Assert.assertArrayEquals;
public class KeyAgreementTest extends BrambleTestCase {
@Test
public void testDeriveSharedSecret() throws Exception {
CryptoComponent crypto =
new CryptoComponentImpl(new TestSecureRandomProvider(), null);
KeyPair aPair = crypto.generateAgreementKeyPair();
KeyPair bPair = crypto.generateAgreementKeyPair();
private final CryptoComponent crypto =
new CryptoComponentImpl(new TestSecureRandomProvider(), null);
private final byte[][] inputs;
public KeyAgreementTest() {
Random random = new Random();
byte[][] inputs = new byte[random.nextInt(10) + 1][];
inputs = new byte[random.nextInt(10) + 1][];
for (int i = 0; i < inputs.length; i++)
inputs[i] = getRandomBytes(random.nextInt(256));
}
@Test
public void testDerivesSharedSecret() throws Exception {
KeyPair aPair = crypto.generateAgreementKeyPair();
KeyPair bPair = crypto.generateAgreementKeyPair();
SecretKey aShared = crypto.deriveSharedSecret(SHARED_SECRET_LABEL,
bPair.getPublic(), aPair, inputs);
SecretKey bShared = crypto.deriveSharedSecret(SHARED_SECRET_LABEL,
aPair.getPublic(), bPair, inputs);
assertArrayEquals(aShared.getBytes(), bShared.getBytes());
}
@Test(expected = GeneralSecurityException.class)
public void testRejectsInvalidPublicKey() throws Exception {
KeyPair keyPair = crypto.generateAgreementKeyPair();
PublicKey invalid = new Curve25519PublicKey(new byte[32]);
crypto.deriveSharedSecret(SHARED_SECRET_LABEL, invalid, keyPair,
inputs);
}
}

View File

@@ -26,7 +26,7 @@ public class KeyEncodingAndParsingTest extends BrambleTestCase {
public void testAgreementPublicKeyLength() throws Exception {
// Generate 10 agreement key pairs
for (int i = 0; i < 10; i++) {
KeyPair keyPair = crypto.generateSignatureKeyPair();
KeyPair keyPair = crypto.generateAgreementKeyPair();
// Check the length of the public key
byte[] publicKey = keyPair.getPublic().getEncoded();
assertTrue(publicKey.length <= MAX_AGREEMENT_PUBLIC_KEY_BYTES);