From c0e07c765ec68dcd5a6c63ed7f51dd8adce6ca31 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 07:50:16 -0700 Subject: [PATCH 1/2] Build(deps): bump rand from 0.8.5 to 0.9.3 (#86) Bumps [rand](https://github.com/rust-random/rand) from 0.8.5 to 0.9.3. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/0.9.3/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.9.3) --- updated-dependencies: - dependency-name: rand dependency-version: 0.9.3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 53 +++++++++++++++++++++++++-------- core/double-ratchets/Cargo.toml | 2 +- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78f4dd8..17e48e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,7 +172,7 @@ dependencies = [ "ed25519-dalek", "generic-array 1.3.5", "hkdf", - "rand_core", + "rand_core 0.6.4", "sha2", "thiserror", "x25519-dalek", @@ -187,7 +187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array 0.14.7", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -258,8 +258,8 @@ dependencies = [ "chacha20poly1305", "chat-sqlite", "hkdf", - "rand", - "rand_core", + "rand 0.9.3", + "rand_core 0.6.4", "safer-ffi", "serde", "storage", @@ -532,7 +532,7 @@ dependencies = [ "double-ratchets", "hex", "prost", - "rand_core", + "rand_core 0.6.4", "safer-ffi", "storage", "tempfile", @@ -729,8 +729,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ec095654a25171c2124e9e3393a930bddbffdc939556c914957a4c3e0a87166" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] @@ -740,7 +750,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", ] [[package]] @@ -752,6 +772,15 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "rusqlite" version = "0.35.0" @@ -897,7 +926,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -947,7 +976,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "rand", + "rand 0.8.5", "syn 1.0.109", ] @@ -1171,7 +1200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core", + "rand_core 0.6.4", "serde", "zeroize", ] @@ -1186,7 +1215,7 @@ dependencies = [ "derive_more", "ed25519", "ed25519-dalek", - "rand", + "rand 0.8.5", "sha2", "x25519-dalek", "zeroize", diff --git a/core/double-ratchets/Cargo.toml b/core/double-ratchets/Cargo.toml index af51920..747718b 100644 --- a/core/double-ratchets/Cargo.toml +++ b/core/double-ratchets/Cargo.toml @@ -14,7 +14,7 @@ required-features = ["headers"] x25519-dalek = { version="2.0.1", features=["static_secrets"] } chacha20poly1305 = "0.10.1" rand_core = "0.6.4" -rand = "0.8.5" +rand = "0.9.3" hkdf = "0.12.4" thiserror = "2" blake2 = "0.10.6" From 94935c28fee1ffe780d031dde092d79b5d8d71b0 Mon Sep 17 00:00:00 2001 From: kaichao Date: Thu, 16 Apr 2026 23:26:19 +0800 Subject: [PATCH 2/2] refactor: remove FFI interfaces from double ratchets (#84) * chore: remove ffi from double ratchet * chore: update doc * chore: format --- Cargo.lock | 1 - core/double-ratchets/Cargo.toml | 8 - core/double-ratchets/README.md | 9 -- .../ffi-nim-example/ffi_nim_example.nimble | 13 -- .../ffi-nim-example/src/ffi_nim_example.nim | 144 ------------------ .../src/bin/generate-headers.rs | 5 - core/double-ratchets/src/ffi/doubleratchet.rs | 81 ---------- core/double-ratchets/src/ffi/key.rs | 22 --- core/double-ratchets/src/ffi/mod.rs | 10 -- core/double-ratchets/src/ffi/utils.rs | 13 -- core/double-ratchets/src/lib.rs | 1 - 11 files changed, 307 deletions(-) delete mode 100644 core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble delete mode 100644 core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim delete mode 100644 core/double-ratchets/src/bin/generate-headers.rs delete mode 100644 core/double-ratchets/src/ffi/doubleratchet.rs delete mode 100644 core/double-ratchets/src/ffi/key.rs delete mode 100644 core/double-ratchets/src/ffi/mod.rs delete mode 100644 core/double-ratchets/src/ffi/utils.rs diff --git a/Cargo.lock b/Cargo.lock index 17e48e0..8e22028 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -260,7 +260,6 @@ dependencies = [ "hkdf", "rand 0.9.3", "rand_core 0.6.4", - "safer-ffi", "serde", "storage", "tempfile", diff --git a/core/double-ratchets/Cargo.toml b/core/double-ratchets/Cargo.toml index 747718b..4d9ea08 100644 --- a/core/double-ratchets/Cargo.toml +++ b/core/double-ratchets/Cargo.toml @@ -6,10 +6,6 @@ edition = "2024" [lib] crate-type = ["rlib", "cdylib"] -[[bin]] -name = "generate-headers" -required-features = ["headers"] - [dependencies] x25519-dalek = { version="2.0.1", features=["static_secrets"] } chacha20poly1305 = "0.10.1" @@ -18,14 +14,10 @@ rand = "0.9.3" hkdf = "0.12.4" thiserror = "2" blake2 = "0.10.6" -safer-ffi = "0.1.13" zeroize = "1.8.2" storage = { workspace = true } serde = "1.0" -[features] -headers = ["safer-ffi/headers"] - [dev-dependencies] sqlite = { package = "chat-sqlite", path = "../sqlite" } tempfile = "3" diff --git a/core/double-ratchets/README.md b/core/double-ratchets/README.md index 974deda..ad33caf 100644 --- a/core/double-ratchets/README.md +++ b/core/double-ratchets/README.md @@ -23,12 +23,3 @@ cargo run --example double_ratchet_basic cargo run --example storage_demo --features storage cargo run --example storage_demo --features sqlcipher ``` - -Run Nim FFI example, - -```bash -# In the root folder (libchat) -cargo build --release -# In ffi-nim-example folder -nimble run -``` diff --git a/core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble b/core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble deleted file mode 100644 index a89d2a5..0000000 --- a/core/double-ratchets/ffi-nim-example/ffi_nim_example.nimble +++ /dev/null @@ -1,13 +0,0 @@ -# Package - -version = "0.1.0" -author = "kaichaosun" -description = "A new awesome nimble package" -license = "MIT" -srcDir = "src" -bin = @["ffi_nim_example"] - - -# Dependencies - -requires "nim >= 2.2.4" diff --git a/core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim b/core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim deleted file mode 100644 index 2437c43..0000000 --- a/core/double-ratchets/ffi-nim-example/src/ffi_nim_example.nim +++ /dev/null @@ -1,144 +0,0 @@ -when defined(macosx): - {.passL: "-Wl,-rpath,@executable_path/../../target/release".} -when defined(linux): - {.passL: "-Wl,-rpath,'$ORIGIN/../../target/release'".} - -# Portable dynlib name with override capability (-d:RLN_LIB:"...") -when defined(macosx): - const DR_LIB* {.strdefine.} = "libdouble_ratchets.dylib" -elif defined(linux): - const DR_LIB* {.strdefine.} = "libdouble_ratchets.so" -elif defined(windows): - const DR_LIB* {.strdefine.} = "double_ratchets.dll" -else: - const DR_LIB* {.strdefine.} = "double_ratchets" - -type FFIRatchetState* = object - -type FFIEncryptResult* = object - -type FFIInstallationKeyPair* = object - -type CSize* = csize_t - -type Vec_uint8* = object - dataPtr*: ptr uint8 - len*: CSize - cap*: CSize - -type Array_uint8_32* {.bycopy.} = object - idx*: array[32, uint8] - -type CResult_Vec_uint8_Vec_uint8* {.bycopy.} = object ## - ok*: Vec_uint8 - err*: Vec_uint8 - -proc double_ratchet_init_receiver*( - shared_secret: Array_uint8_32, keypair: ptr FFIInstallationKeyPair -): ptr FFIRatchetState {.importc, dynlib: DR_LIB.} - -proc double_ratchet_init_sender*( - shared_secret: Array_uint8_32, remote_pub: Array_uint8_32 -): ptr FFIRatchetState {.importc, dynlib: DR_LIB.} - -proc double_ratchet_encrypt_message*( - state: ptr FFIRatchetState, plaintext: ptr Vec_uint8 -): ptr FFIEncryptResult {.importc, dynlib: DR_LIB.} - -proc double_ratchet_descrypt_message*( - state: ptr FFIRatchetState, encrypted: ptr FFIEncryptResult -): CResult_Vec_uint8_Vec_uint8 {.importc, dynlib: DR_LIB.} - -proc ratchet_state_destroy*(state: ptr FFIRatchetState) {.importc, dynlib: DR_LIB.} - -proc encrypt_result_destroy*(result: ptr FFIEncryptResult) {.importc, dynlib: DR_LIB.} - -proc installation_key_pair_generate*(): ptr FFIInstallationKeyPair {. - importc, dynlib: DR_LIB -.} - -proc installation_key_pair_public*( - keypair: ptr FFIInstallationKeyPair -): Array_uint8_32 {.importc, dynlib: DR_LIB.} - -proc installation_key_pair_destroy*( - keypair: ptr FFIInstallationKeyPair -) {.importc, dynlib: DR_LIB.} - -proc ffi_c_string_free*(s: Vec_uint8) {.importc, cdecl, dynlib: DR_LIB.} - -proc asString*(v: Vec_uint8): string = - if v.dataPtr.isNil or v.len == 0: - return "" - result = newString(v.len.int) - copyMem(addr result[0], v.dataPtr, v.len.int) - -when isMainModule: - echo("start run") - - # === Shared secret (like X3DH) === - var sharedSecret: Array_uint8_32 - for i in 0 .. 31: - sharedSecret.idx[i] = 42'u8 - - # === Bob generates DH keypair === - let bobKey = installation_key_pair_generate() - let bobPub = installation_key_pair_public(bobKey) - echo("bob public key:", bobPub) - - # === Alice initializes as sender === - let alice = double_ratchet_init_sender(sharedSecret, bobPub) - # # === Bob initializes as receiver === - let bob = double_ratchet_init_receiver(sharedSecret, bobKey) - - # # === Alice sends message to Bob === - var msg1: array[3, uint8] = [11'u8, 12, 13] - var msg1Vec = Vec_uint8( - dataPtr: cast[ptr uint8](addr msg1[0]), len: CSize(msg1.len), cap: CSize(msg1.len) - ) - - let enc1 = double_ratchet_encrypt_message(alice, addr msg1Vec) - let dec1 = double_ratchet_descrypt_message(bob, enc1) - - encrypt_result_destroy(enc1) - - if dec1.err.dataPtr != nil: - echo "Bob failed to decrypt: ", asString(dec1.err) - ffi_c_string_free(dec1.err) - ratchet_state_destroy(alice) - ratchet_state_destroy(bob) - installation_key_pair_destroy(bobKey) - quit 1 - let res1 = dec1.ok - var plaintext1: array[3, uint8] - copyMem(addr plaintext1[0], res1.dataPtr, res1.len.int) - echo "Bob received: ", plaintext1 - - # # === Bob replies (triggers DH ratchet) === - var msg2: array[3, uint8] = [1'u8, 2, 3] - var msg2Vec = Vec_uint8( - dataPtr: cast[ptr uint8](addr msg2[0]), len: CSize(msg1.len), cap: CSize(msg1.len) - ) - let enc2 = double_ratchet_encrypt_message(bob, addr msg2Vec) - let dec2 = double_ratchet_descrypt_message(alice, enc2) - - encrypt_result_destroy(enc2) - - if dec2.err.dataPtr != nil: - echo "Alice failed to decrypt: ", asString(dec2.err) - ffi_c_string_free(dec2.err) - ratchet_state_destroy(alice) - ratchet_state_destroy(bob) - installation_key_pair_destroy(bobKey) - quit 1 - let res2 = dec2.ok - var plaintext2: array[3, uint8] - copyMem(addr plaintext2[0], res2.dataPtr, res2.len.int) - echo "Alice received: ", plaintext2 - - # # === Cleanup === - ratchet_state_destroy(alice) - ratchet_state_destroy(bob) - installation_key_pair_destroy(bobKey) - - echo("==end==\n") diff --git a/core/double-ratchets/src/bin/generate-headers.rs b/core/double-ratchets/src/bin/generate-headers.rs deleted file mode 100644 index 4c853ea..0000000 --- a/core/double-ratchets/src/bin/generate-headers.rs +++ /dev/null @@ -1,5 +0,0 @@ -use double_ratchets::ffi; - -fn main() -> std::io::Result<()> { - ffi::generate_headers() -} diff --git a/core/double-ratchets/src/ffi/doubleratchet.rs b/core/double-ratchets/src/ffi/doubleratchet.rs deleted file mode 100644 index e09cebd..0000000 --- a/core/double-ratchets/src/ffi/doubleratchet.rs +++ /dev/null @@ -1,81 +0,0 @@ -use safer_ffi::prelude::*; -use x25519_dalek::PublicKey; - -use crate::{ - Header, RatchetState, - ffi::{key::FFIInstallationKeyPair, utils::CResult}, -}; - -#[derive_ReprC] -#[repr(opaque)] -pub struct FFIRatchetState(pub(crate) RatchetState); - -#[derive_ReprC] -#[repr(opaque)] -pub struct FFIEncryptResult { - pub ciphertext: Vec, - pub header: Header, -} - -#[ffi_export] -fn double_ratchet_init_sender( - shared_secret: [u8; 32], - remote_pub: [u8; 32], -) -> repr_c::Box { - let state = RatchetState::init_sender(shared_secret, PublicKey::from(remote_pub)); - Box::new(FFIRatchetState(state)).into() -} - -#[ffi_export] -fn double_ratchet_init_receiver( - shared_secret: [u8; 32], - keypair: &FFIInstallationKeyPair, -) -> repr_c::Box { - let state = RatchetState::init_receiver(shared_secret, keypair.0.clone()); - Box::new(FFIRatchetState(state)).into() -} - -#[ffi_export] -fn double_ratchet_encrypt_message( - state: &mut FFIRatchetState, - plaintext: &repr_c::Vec, -) -> repr_c::Box { - let encrypted = state.0.encrypt_message(plaintext); - let result = FFIEncryptResult { - ciphertext: encrypted.0, - header: encrypted.1, - }; - Box::new(result).into() -} - -//TODO rename decrypt -#[ffi_export] -fn double_ratchet_descrypt_message( - state: &mut FFIRatchetState, - encrypted: &FFIEncryptResult, -) -> CResult, repr_c::String> { - let decrypted = state - .0 - .decrypt_message(&encrypted.ciphertext, encrypted.header.clone()); - - match decrypted { - Ok(plaintext) => CResult { - ok: Some(plaintext.into()), - err: None, - }, - Err(err) => CResult { - ok: None, - err: Some(err.to_string().into()), - }, - } -} - -#[ffi_export] -fn ratchet_state_destroy(state: repr_c::Box) { - drop(state) -} - -#[ffi_export] -fn encrypt_result_destroy(result: repr_c::Box) { - drop(result) -} diff --git a/core/double-ratchets/src/ffi/key.rs b/core/double-ratchets/src/ffi/key.rs deleted file mode 100644 index ee8a496..0000000 --- a/core/double-ratchets/src/ffi/key.rs +++ /dev/null @@ -1,22 +0,0 @@ -use safer_ffi::prelude::*; - -use crate::InstallationKeyPair; - -#[derive_ReprC] -#[repr(opaque)] -pub struct FFIInstallationKeyPair(pub(crate) InstallationKeyPair); - -#[ffi_export] -fn installation_key_pair_generate() -> repr_c::Box { - Box::new(FFIInstallationKeyPair(InstallationKeyPair::generate())).into() -} - -#[ffi_export] -fn installation_key_pair_public(keypair: &FFIInstallationKeyPair) -> [u8; 32] { - keypair.0.public().clone().to_bytes() -} - -#[ffi_export] -fn installation_key_pair_destroy(keypair: repr_c::Box) { - drop(keypair) -} diff --git a/core/double-ratchets/src/ffi/mod.rs b/core/double-ratchets/src/ffi/mod.rs deleted file mode 100644 index f67b19a..0000000 --- a/core/double-ratchets/src/ffi/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod doubleratchet; -pub mod key; -pub mod utils; - -#[cfg(feature = "headers")] -pub fn generate_headers() -> std::io::Result<()> { - safer_ffi::headers::builder() - .to_file("double_ratchet.h")? - .generate() -} diff --git a/core/double-ratchets/src/ffi/utils.rs b/core/double-ratchets/src/ffi/utils.rs deleted file mode 100644 index f50033f..0000000 --- a/core/double-ratchets/src/ffi/utils.rs +++ /dev/null @@ -1,13 +0,0 @@ -use safer_ffi::prelude::*; - -#[derive_ReprC] -#[repr(C)] -pub struct CResult { - pub ok: Option, - pub err: Option, -} - -#[ffi_export] -pub fn ffi_c_string_free(s: repr_c::String) { - drop(s); -} diff --git a/core/double-ratchets/src/lib.rs b/core/double-ratchets/src/lib.rs index b8778fc..4a5291e 100644 --- a/core/double-ratchets/src/lib.rs +++ b/core/double-ratchets/src/lib.rs @@ -1,6 +1,5 @@ pub mod aead; pub mod errors; -pub mod ffi; pub mod hkdf; pub mod keypair; pub mod reader;