mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Add tests for hashing public keys into shared secret.
This commit is contained in:
@@ -14,9 +14,9 @@ import java.security.GeneralSecurityException;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.SHARED_SECRET_LABEL;
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
@@ -38,6 +38,7 @@ public class KeyAgreementTest extends BrambleTestCase {
|
|||||||
|
|
||||||
private final CryptoComponent crypto =
|
private final CryptoComponent crypto =
|
||||||
new CryptoComponentImpl(new TestSecureRandomProvider(), null);
|
new CryptoComponentImpl(new TestSecureRandomProvider(), null);
|
||||||
|
private final String label = getRandomString(123);
|
||||||
private final byte[][] inputs;
|
private final byte[][] inputs;
|
||||||
|
|
||||||
public KeyAgreementTest() {
|
public KeyAgreementTest() {
|
||||||
@@ -51,9 +52,9 @@ public class KeyAgreementTest extends BrambleTestCase {
|
|||||||
public void testDerivesSharedSecret() throws Exception {
|
public void testDerivesSharedSecret() throws Exception {
|
||||||
KeyPair aPair = crypto.generateAgreementKeyPair();
|
KeyPair aPair = crypto.generateAgreementKeyPair();
|
||||||
KeyPair bPair = crypto.generateAgreementKeyPair();
|
KeyPair bPair = crypto.generateAgreementKeyPair();
|
||||||
SecretKey aShared = crypto.deriveSharedSecret(SHARED_SECRET_LABEL,
|
SecretKey aShared = crypto.deriveSharedSecret(label,
|
||||||
bPair.getPublic(), aPair, inputs);
|
bPair.getPublic(), aPair, inputs);
|
||||||
SecretKey bShared = crypto.deriveSharedSecret(SHARED_SECRET_LABEL,
|
SecretKey bShared = crypto.deriveSharedSecret(label,
|
||||||
aPair.getPublic(), bPair, inputs);
|
aPair.getPublic(), bPair, inputs);
|
||||||
assertArrayEquals(aShared.getBytes(), bShared.getBytes());
|
assertArrayEquals(aShared.getBytes(), bShared.getBytes());
|
||||||
}
|
}
|
||||||
@@ -62,8 +63,7 @@ public class KeyAgreementTest extends BrambleTestCase {
|
|||||||
public void testRejectsInvalidPublicKey() throws Exception {
|
public void testRejectsInvalidPublicKey() throws Exception {
|
||||||
KeyPair keyPair = crypto.generateAgreementKeyPair();
|
KeyPair keyPair = crypto.generateAgreementKeyPair();
|
||||||
PublicKey invalid = new AgreementPublicKey(new byte[32]);
|
PublicKey invalid = new AgreementPublicKey(new byte[32]);
|
||||||
crypto.deriveSharedSecret(SHARED_SECRET_LABEL, invalid, keyPair,
|
crypto.deriveSharedSecret(label, invalid, keyPair, inputs);
|
||||||
inputs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -88,15 +88,68 @@ public class KeyAgreementTest extends BrambleTestCase {
|
|||||||
Curve25519 curve25519 = Curve25519.getInstance("java");
|
Curve25519 curve25519 = Curve25519.getInstance("java");
|
||||||
|
|
||||||
// Flip the unused most significant bit of the little-endian public key
|
// Flip the unused most significant bit of the little-endian public key
|
||||||
byte[] aPubEquivalent = aPub.clone();
|
byte[] aPubEquiv = aPub.clone();
|
||||||
aPubEquivalent[31] ^= (byte) 128;
|
aPubEquiv[31] ^= (byte) 128;
|
||||||
|
|
||||||
// The public keys should be different but give the same shared secret
|
// The public keys should be different but give the same shared secret
|
||||||
assertFalse(Arrays.equals(aPub, aPubEquivalent));
|
assertFalse(Arrays.equals(aPub, aPubEquiv));
|
||||||
assertArrayEquals(sharedSecret,
|
assertArrayEquals(sharedSecret,
|
||||||
curve25519.calculateAgreement(aPub, bPriv));
|
curve25519.calculateAgreement(aPub, bPriv));
|
||||||
assertArrayEquals(sharedSecret,
|
assertArrayEquals(sharedSecret,
|
||||||
curve25519.calculateAgreement(aPubEquivalent, bPriv));
|
curve25519.calculateAgreement(aPubEquiv, bPriv));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDerivesSameSharedSecretFromEquivalentPublicKeyWithoutPublicKeysHashedIn()
|
||||||
|
throws Exception {
|
||||||
|
KeyPair aPair = crypto.generateAgreementKeyPair();
|
||||||
|
KeyPair bPair = crypto.generateAgreementKeyPair();
|
||||||
|
|
||||||
|
// Flip the unused most significant bit of the little-endian public key
|
||||||
|
byte[] aPub = aPair.getPublic().getEncoded();
|
||||||
|
byte[] aPubEquiv = aPub.clone();
|
||||||
|
aPubEquiv[31] ^= (byte) 128;
|
||||||
|
KeyPair aPairEquiv = new KeyPair(new AgreementPublicKey(aPubEquiv),
|
||||||
|
aPair.getPrivate());
|
||||||
|
|
||||||
|
// The public keys should be different but give the same shared secret
|
||||||
|
assertFalse(Arrays.equals(aPub, aPubEquiv));
|
||||||
|
SecretKey shared = crypto.deriveSharedSecret(label,
|
||||||
|
aPair.getPublic(), bPair);
|
||||||
|
SecretKey sharedEquiv = crypto.deriveSharedSecret(label,
|
||||||
|
aPairEquiv.getPublic(), bPair);
|
||||||
|
assertArrayEquals(shared.getBytes(), sharedEquiv.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDerivesDifferentSharedSecretFromEquivalentPublicKeyWithPublicKeysHashedIn()
|
||||||
|
throws Exception {
|
||||||
|
KeyPair aPair = crypto.generateAgreementKeyPair();
|
||||||
|
KeyPair bPair = crypto.generateAgreementKeyPair();
|
||||||
|
|
||||||
|
// Flip the unused most significant bit of the little-endian public key
|
||||||
|
byte[] aPub = aPair.getPublic().getEncoded();
|
||||||
|
byte[] aPubEquiv = aPub.clone();
|
||||||
|
aPubEquiv[31] ^= (byte) 128;
|
||||||
|
KeyPair aPairEquiv = new KeyPair(new AgreementPublicKey(aPubEquiv),
|
||||||
|
aPair.getPrivate());
|
||||||
|
|
||||||
|
// The public keys should be different and give different shared secrets
|
||||||
|
assertFalse(Arrays.equals(aPub, aPubEquiv));
|
||||||
|
SecretKey shared = deriveSharedSecretWithPublicKeysHashedIn(label,
|
||||||
|
aPair.getPublic(), bPair);
|
||||||
|
SecretKey sharedEquiv = deriveSharedSecretWithPublicKeysHashedIn(label,
|
||||||
|
aPairEquiv.getPublic(), bPair);
|
||||||
|
assertFalse(Arrays.equals(shared.getBytes(), sharedEquiv.getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SecretKey deriveSharedSecretWithPublicKeysHashedIn(String label,
|
||||||
|
PublicKey publicKey, KeyPair keyPair) throws Exception {
|
||||||
|
byte[][] inputs = new byte[][] {
|
||||||
|
publicKey.getEncoded(),
|
||||||
|
keyPair.getPublic().getEncoded()
|
||||||
|
};
|
||||||
|
return crypto.deriveSharedSecret(label, publicKey, keyPair, inputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] parsePrivateKey(String hex) {
|
private byte[] parsePrivateKey(String hex) {
|
||||||
|
|||||||
Reference in New Issue
Block a user