-
Notifications
You must be signed in to change notification settings - Fork 29
feat(ffi): add provekit-ffi #198
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
32b11e7 to
e1044b2
Compare
af6beed to
6f62ea3
Compare
6f62ea3 to
92c13c6
Compare
- Update CI workflow to use nightly-2025-10-20 matching rust-toolchain.toml - Fix MSRV warning: remove const from num_entries (requires Rust 1.87+) - Fix doc-lazy-continuation warning in witness_builder.rs - Fix needless_borrows_for_generic_args in FFI prove functions
Wrap FFI functions with catch_panic to prevent undefined behavior from stack unwinding across FFI boundary. This is critical for mobile platforms where panics must not propagate to C/Swift/Kotlin.
4a84f87 to
35ccf13
Compare
Allows host applications to provide custom memory allocation functions for memory tracking and management. Falls back to system allocator when not configured. Optimized for minimal overhead in the default case.
| /// # Safety | ||
| /// | ||
| /// The caller must ensure that `ptr` is a valid null-terminated C string. | ||
| pub unsafe fn c_str_to_str(ptr: *const c_char) -> Result<&'static str, PKError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returns 'static lifetime but the underlying C string has no such guarantee if the caller frees the string while Rust code holds the reference.
| #[no_mangle] | ||
| pub unsafe extern "C" fn pk_free_buf(buf: PKBuf) { | ||
| if !buf.ptr.is_null() && buf.len > 0 { | ||
| drop(Vec::from_raw_parts(buf.ptr, buf.len, buf.len)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the original Vec had capacity > len, we're reconstructing with wrong capacity.
example :
let mut v: Vec<u8> = Vec::with_capacity(100); // capacity = 100
v.push(1);
v.push(2);
v.push(3);
// Now: len = 3, capacity = 100
and then in types.rs
pub fn from_vec(mut v: Vec<u8>) -> Self {
let ptr = v.as_mut_ptr();
let len = v.len(); // len = 3
std::mem::forget(v); // capacity (100)
Self { ptr, len } // PKBuf { ptr, len: 3 }
}
and then pk_free_buf reconstructs with wrong capacity
drop(Vec::from_raw_parts(buf.ptr, buf.len, buf.len));
// len=3 cap=3 (was 100)
the allocator allocated 100 bytes but only 3 bytes were freed
| catch_panic(PKError::ProofError.into(), || { | ||
| let out_buf = match out_buf.as_mut() { | ||
| Some(buf) => buf, | ||
| None => return PKError::InvalidInput.into(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unreachable condition
| serde.workspace = true | ||
| serde_json.workspace = true | ||
| postcard.workspace = true | ||
| tracing.workspace = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused dependency
Summary
Adds a new
provekit-fficrate that provides C-compatible FFI bindings for ProveKit, enabling integration with multiple programming languages and platforms including mobile (iOS, Android), desktop, web, and embedded systems.Features
PKBufPKErrorenum) with clear semanticsAPI
Functions
pk_init()pk_prove_to_file()pk_prove_to_json()pk_free_buf()Error Codes
PK_SUCCESSPK_INVALID_INPUTPK_SCHEME_READ_ERRORPK_WITNESS_READ_ERRORPK_PROOF_ERRORPK_SERIALIZATION_ERRORPK_UTF8_ERRORPK_FILE_WRITE_ERRORAdditional Changes
nightly-2025-10-20matchingrust-toolchain.tomlprovekit-common