mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-05-12 21:19:44 +00:00
Merge branch 'main' into feat/add-flake
This commit is contained in:
commit
6286611de7
54
Cargo.lock
generated
54
Cargo.lock
generated
@ -172,7 +172,7 @@ dependencies = [
|
|||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
"generic-array 1.3.5",
|
"generic-array 1.3.5",
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"sha2",
|
"sha2",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"x25519-dalek",
|
"x25519-dalek",
|
||||||
@ -187,7 +187,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array 0.14.7",
|
"generic-array 0.14.7",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -258,9 +258,8 @@ dependencies = [
|
|||||||
"chacha20poly1305",
|
"chacha20poly1305",
|
||||||
"chat-sqlite",
|
"chat-sqlite",
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"rand",
|
"rand 0.9.3",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"safer-ffi",
|
|
||||||
"serde",
|
"serde",
|
||||||
"storage",
|
"storage",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@ -532,7 +531,7 @@ dependencies = [
|
|||||||
"double-ratchets",
|
"double-ratchets",
|
||||||
"hex",
|
"hex",
|
||||||
"prost",
|
"prost",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"safer-ffi",
|
"safer-ffi",
|
||||||
"storage",
|
"storage",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@ -729,8 +728,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.3.1",
|
||||||
"rand_core",
|
"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]]
|
[[package]]
|
||||||
@ -740,7 +749,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"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]]
|
[[package]]
|
||||||
@ -752,6 +771,15 @@ dependencies = [
|
|||||||
"getrandom 0.2.17",
|
"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]]
|
[[package]]
|
||||||
name = "rusqlite"
|
name = "rusqlite"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
@ -897,7 +925,7 @@ version = "2.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -947,7 +975,7 @@ dependencies = [
|
|||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1171,7 +1199,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
|
checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curve25519-dalek",
|
"curve25519-dalek",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"serde",
|
"serde",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
@ -1186,7 +1214,7 @@ dependencies = [
|
|||||||
"derive_more",
|
"derive_more",
|
||||||
"ed25519",
|
"ed25519",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"sha2",
|
"sha2",
|
||||||
"x25519-dalek",
|
"x25519-dalek",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
|
|||||||
@ -6,26 +6,18 @@ edition = "2024"
|
|||||||
[lib]
|
[lib]
|
||||||
crate-type = ["rlib", "cdylib"]
|
crate-type = ["rlib", "cdylib"]
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "generate-headers"
|
|
||||||
required-features = ["headers"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
x25519-dalek = { version="2.0.1", features=["static_secrets"] }
|
x25519-dalek = { version="2.0.1", features=["static_secrets"] }
|
||||||
chacha20poly1305 = "0.10.1"
|
chacha20poly1305 = "0.10.1"
|
||||||
rand_core = "0.6.4"
|
rand_core = "0.6.4"
|
||||||
rand = "0.8.5"
|
rand = "0.9.3"
|
||||||
hkdf = "0.12.4"
|
hkdf = "0.12.4"
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
blake2 = "0.10.6"
|
blake2 = "0.10.6"
|
||||||
safer-ffi = "0.1.13"
|
|
||||||
zeroize = "1.8.2"
|
zeroize = "1.8.2"
|
||||||
storage = { workspace = true }
|
storage = { workspace = true }
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
|
|
||||||
[features]
|
|
||||||
headers = ["safer-ffi/headers"]
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
sqlite = { package = "chat-sqlite", path = "../sqlite" }
|
sqlite = { package = "chat-sqlite", path = "../sqlite" }
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
|
|||||||
@ -23,12 +23,3 @@ cargo run --example double_ratchet_basic
|
|||||||
cargo run --example storage_demo --features storage
|
cargo run --example storage_demo --features storage
|
||||||
cargo run --example storage_demo --features sqlcipher
|
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
|
|
||||||
```
|
|
||||||
|
|||||||
@ -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"
|
|
||||||
@ -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 ## <No documentation available>
|
|
||||||
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")
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
use double_ratchets::ffi;
|
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
|
||||||
ffi::generate_headers()
|
|
||||||
}
|
|
||||||
@ -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<u8>,
|
|
||||||
pub header: Header,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn double_ratchet_init_sender(
|
|
||||||
shared_secret: [u8; 32],
|
|
||||||
remote_pub: [u8; 32],
|
|
||||||
) -> repr_c::Box<FFIRatchetState> {
|
|
||||||
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<FFIRatchetState> {
|
|
||||||
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<u8>,
|
|
||||||
) -> repr_c::Box<FFIEncryptResult> {
|
|
||||||
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::Vec<u8>, 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<FFIRatchetState>) {
|
|
||||||
drop(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn encrypt_result_destroy(result: repr_c::Box<FFIEncryptResult>) {
|
|
||||||
drop(result)
|
|
||||||
}
|
|
||||||
@ -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<FFIInstallationKeyPair> {
|
|
||||||
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<FFIInstallationKeyPair>) {
|
|
||||||
drop(keypair)
|
|
||||||
}
|
|
||||||
@ -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()
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
use safer_ffi::prelude::*;
|
|
||||||
|
|
||||||
#[derive_ReprC]
|
|
||||||
#[repr(C)]
|
|
||||||
pub struct CResult<T: ReprC, Err: ReprC> {
|
|
||||||
pub ok: Option<T>,
|
|
||||||
pub err: Option<Err>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
pub fn ffi_c_string_free(s: repr_c::String) {
|
|
||||||
drop(s);
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
pub mod aead;
|
pub mod aead;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod ffi;
|
|
||||||
pub mod hkdf;
|
pub mod hkdf;
|
||||||
pub mod keypair;
|
pub mod keypair;
|
||||||
pub mod reader;
|
pub mod reader;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user