Skip to content

Commit ff09619

Browse files
rolfeschmidtjrose-signalmoiseev-signal
committed
Add Kyber KEM and implement PQXDH protocol
Co-authored-by: Jordan Rose <jrose@signal.org> Co-authored-by: Max Moiseev <moiseev@signal.org>
1 parent 2b46ae1 commit ff09619

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2720
-278
lines changed

Cargo.lock

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

java/build_jni.sh

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,19 @@ then
3434
# Use small BoringSSL curve tables to reduce binary size on Android.
3535
export CFLAGS="-DOPENSSL_SMALL -flto=thin ${CFLAGS:-}"
3636

37-
# Use the Android NDK's prebuilt Clang+lld as Rust's linker.
37+
# Use the Android NDK's prebuilt Clang+lld as pqcrypto's compiler and Rust's linker.
3838
ANDROID_TOOLCHAIN_DIR=$(echo "${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt"/*/bin/)
39-
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${ANDROID_TOOLCHAIN_DIR}/aarch64-linux-android21-clang"
40-
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${ANDROID_TOOLCHAIN_DIR}/armv7a-linux-androideabi21-clang"
41-
export CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="${ANDROID_TOOLCHAIN_DIR}/x86_64-linux-android21-clang"
42-
export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="${ANDROID_TOOLCHAIN_DIR}/i686-linux-android21-clang"
39+
export CC_aarch64_linux_android="${ANDROID_TOOLCHAIN_DIR}/aarch64-linux-android21-clang"
40+
export CC_armv7_linux_androideabi="${ANDROID_TOOLCHAIN_DIR}/armv7a-linux-androideabi21-clang"
41+
export CC_x86_64_linux_android="${ANDROID_TOOLCHAIN_DIR}/x86_64-linux-android21-clang"
42+
export CC_i686_linux_android="${ANDROID_TOOLCHAIN_DIR}/i686-linux-android21-clang"
43+
44+
export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${CC_aarch64_linux_android}"
45+
export CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="${CC_armv7_linux_androideabi}"
46+
export CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="${CC_x86_64_linux_android}"
47+
export CARGO_TARGET_I686_LINUX_ANDROID_LINKER="${CC_i686_linux_android}"
48+
49+
export TARGET_AR="${ANDROID_TOOLCHAIN_DIR}/llvm-ar"
4350
export RUSTFLAGS="-C link-arg=-fuse-ld=lld ${RUSTFLAGS:-}"
4451

4552
echo_then_run cargo build -p libsignal-jni --release -Z unstable-options --target aarch64-linux-android --out-dir "${ANDROID_LIB_DIR}/arm64-v8a"

java/client/src/test/java/org/signal/libsignal/metadata/SealedSessionCipherTest.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.signal.libsignal.protocol.ecc.ECPublicKey;
2525
import org.signal.libsignal.protocol.groups.GroupCipher;
2626
import org.signal.libsignal.protocol.groups.GroupSessionBuilder;
27+
import org.signal.libsignal.protocol.kem.KEMKeyPair;
28+
import org.signal.libsignal.protocol.kem.KEMKeyType;
2729
import org.signal.libsignal.protocol.message.CiphertextMessage;
2830
import org.signal.libsignal.protocol.message.DecryptionErrorMessage;
2931
import org.signal.libsignal.protocol.message.PlaintextContent;
@@ -32,12 +34,12 @@
3234
import org.signal.libsignal.protocol.state.PreKeyRecord;
3335
import org.signal.libsignal.protocol.state.SessionRecord;
3436
import org.signal.libsignal.protocol.state.SignedPreKeyRecord;
37+
import org.signal.libsignal.protocol.state.KyberPreKeyRecord;
3538

3639
import org.signal.libsignal.internal.Native;
3740
import org.signal.libsignal.internal.NativeHandleGuard;
3841

3942
import org.signal.libsignal.protocol.util.Hex;
40-
import org.signal.libsignal.protocol.util.Pair;
4143

4244
import java.util.ArrayList;
4345
import java.util.Arrays;
@@ -55,6 +57,14 @@ private static SignedPreKeyRecord generateSignedPreKey(IdentityKeyPair identityK
5557
return new SignedPreKeyRecord(signedPreKeyId, System.currentTimeMillis(), keyPair, signature);
5658
}
5759

60+
private static KyberPreKeyRecord generateKyberPreKey(IdentityKeyPair identityKeyPair, int kyberPreKeyId)
61+
throws InvalidKeyException {
62+
KEMKeyPair keyPair = KEMKeyPair.generate(KEMKeyType.KYBER_1024);
63+
byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
64+
65+
return new KyberPreKeyRecord(kyberPreKeyId, System.currentTimeMillis(), keyPair, signature);
66+
}
67+
5868
public void testEncryptDecrypt() throws UntrustedIdentityException, InvalidKeyException, InvalidCertificateException, InvalidMetadataMessageException, ProtocolDuplicateMessageException, ProtocolUntrustedIdentityException, ProtocolLegacyMessageException, ProtocolInvalidKeyException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolInvalidMessageException, ProtocolInvalidKeyIdException, ProtocolNoSessionException, SelfSendException {
5969
TestInMemorySignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
6070
TestInMemorySignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();
@@ -201,8 +211,9 @@ public void testEncryptGroupWithBadRegistrationId() throws UntrustedIdentityExce
201211
ECKeyPair bobPreKey = Curve.generateKeyPair();
202212
IdentityKeyPair bobIdentityKey = bobStore.getIdentityKeyPair();
203213
SignedPreKeyRecord bobSignedPreKey = generateSignedPreKey(bobIdentityKey, 2);
214+
KyberPreKeyRecord bobKyberPreKey = generateKyberPreKey(bobIdentityKey, 12);
204215

205-
PreKeyBundle bobBundle = new PreKeyBundle(0x4000, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey());
216+
PreKeyBundle bobBundle = new PreKeyBundle(0x4000, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey(), 12, bobKyberPreKey.getKeyPair().getPublicKey(), bobKyberPreKey.getSignature());
206217
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, bobAddress);
207218
aliceSessionBuilder.process(bobBundle);
208219

@@ -239,16 +250,18 @@ public void testEncryptGroupWithManyRecipients() throws UntrustedIdentityExcepti
239250
ECKeyPair bobPreKey = Curve.generateKeyPair();
240251
IdentityKeyPair bobIdentityKey = bobStore.getIdentityKeyPair();
241252
SignedPreKeyRecord bobSignedPreKey = generateSignedPreKey(bobIdentityKey, 2);
253+
KyberPreKeyRecord bobKyberPreKey = generateKyberPreKey(bobIdentityKey, 12);
242254

243-
PreKeyBundle bobBundle = new PreKeyBundle(0x1234, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey());
255+
PreKeyBundle bobBundle = new PreKeyBundle(0x1234, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey(), 12, bobKyberPreKey.getKeyPair().getPublicKey(), bobKyberPreKey.getSignature());
244256
SessionBuilder aliceSessionBuilderForBob = new SessionBuilder(aliceStore, bobAddress);
245257
aliceSessionBuilderForBob.process(bobBundle);
246258

247259
ECKeyPair carolPreKey = Curve.generateKeyPair();
248260
IdentityKeyPair carolIdentityKey = carolStore.getIdentityKeyPair();
249261
SignedPreKeyRecord carolSignedPreKey = generateSignedPreKey(carolIdentityKey, 2);
262+
KyberPreKeyRecord carolKyberPreKey = generateKyberPreKey(carolIdentityKey, 12);
250263

251-
PreKeyBundle carolBundle = new PreKeyBundle(0x1111, 1, 1, carolPreKey.getPublicKey(), 2, carolSignedPreKey.getKeyPair().getPublicKey(), carolSignedPreKey.getSignature(), carolIdentityKey.getPublicKey());
264+
PreKeyBundle carolBundle = new PreKeyBundle(0x1111, 1, 1, carolPreKey.getPublicKey(), 2, carolSignedPreKey.getKeyPair().getPublicKey(), carolSignedPreKey.getSignature(), carolIdentityKey.getPublicKey(), 12, carolKyberPreKey.getKeyPair().getPublicKey(), carolKyberPreKey.getSignature());
252265
SessionBuilder aliceSessionBuilderForCarol = new SessionBuilder(aliceStore, carolAddress);
253266
aliceSessionBuilderForCarol.process(carolBundle);
254267

@@ -384,13 +397,14 @@ private void initializeSessions(TestInMemorySignalProtocolStore aliceStore, Test
384397
ECKeyPair bobPreKey = Curve.generateKeyPair();
385398
IdentityKeyPair bobIdentityKey = bobStore.getIdentityKeyPair();
386399
SignedPreKeyRecord bobSignedPreKey = generateSignedPreKey(bobIdentityKey, 2);
400+
KyberPreKeyRecord bobKyberPreKey = generateKyberPreKey(bobIdentityKey, 12);
387401

388-
PreKeyBundle bobBundle = new PreKeyBundle(1, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey());
402+
PreKeyBundle bobBundle = new PreKeyBundle(1, 1, 1, bobPreKey.getPublicKey(), 2, bobSignedPreKey.getKeyPair().getPublicKey(), bobSignedPreKey.getSignature(), bobIdentityKey.getPublicKey(), 12, bobKyberPreKey.getKeyPair().getPublicKey(), bobKyberPreKey.getSignature());
389403
SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, bobAddress);
390404
aliceSessionBuilder.process(bobBundle);
391405

392406
bobStore.storeSignedPreKey(2, bobSignedPreKey);
407+
bobStore.storeKyberPreKey(12, bobKyberPreKey);
393408
bobStore.storePreKey(1, new PreKeyRecord(1, bobPreKey));
394-
395409
}
396410
}

0 commit comments

Comments
 (0)