Skip to content
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

Swift integration #2

Merged
merged 3 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ Cargo.lock
# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

*.run
*.run
*.a
*.so
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,37 @@ Bridge the gap between Swift and the `noir_rs` library, offering Swift developer
- 🌉 Effortless interfacing between Swift and Rust.
- 🔒 Secure zkSNARK proof generation and verification.

## 📦 Build
## 📦 Rust Build

```bash
cargo build
```

## 🧪 Testing
## 🧪 Rust Testing

Ensure the reliability and robustness of your bridge with the provided tests:

```bash
cargo test
```

## 📦 Swift Build

```bash
# copy barretenberg lib to the swift directory
cp target/debug/build/barretenberg-<hash>/out/lib/libbarretenberg.a swift/
# copy noir_swift lib to the swift directory
cp target/debug/libnoir_swift.a swift/

cd swift

# compile swift project
./build

# run the program
./main.run
```

## 🎯 Quick Usage

We provide two main functions for the bridge:
Expand All @@ -35,8 +52,13 @@ We provide two main functions for the bridge:
2. **verify_swift**: Verifies a given zkSNARK proof against a circuit and its verification key.

```rust
fn prove_swift(circuit_bytecode: String, initial_witness_vec_raw: Vec<i128>) -> Result<Proof, String>
fn verify_swift(circuit_bytecode: String, proof: Proof) -> Result<bool, String>
pub struct Proof {
pub proof: Vec<u8>,
pub verification_key: Vec<u8>,
}

fn prove_swift(circuit_bytecode: String, initial_witness_vec_raw: Vec<i32>) -> Option<Proof>;
fn verify_swift(circuit_bytecode: String, proof: Proof) -> Option<bool>;
```

## 🔍 Example
Expand Down
3 changes: 1 addition & 2 deletions generated/noir_swift/noir_swift.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// File automatically generated by swift-bridge.
#include <stdint.h>
#include <stdbool.h>
typedef struct Proof Proof;
void __swift_bridge__$Proof$_free(void* self);

Expand All @@ -14,6 +13,6 @@ uintptr_t __swift_bridge__$Vec_Proof$len(void* vec_ptr);
void* __swift_bridge__$Vec_Proof$as_ptr(void* vec_ptr);

void* __swift_bridge__$prove_swift(void* circuit_bytecode, void* initial_witness_vec_raw);
bool __swift_bridge__$verify_swift(void* circuit_bytecode, void* proof);
struct __private__OptionBool __swift_bridge__$verify_swift(void* circuit_bytecode, void* proof);


8 changes: 4 additions & 4 deletions generated/noir_swift/noir_swift.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
public func prove_swift<GenericIntoRustString: IntoRustString>(_ circuit_bytecode: GenericIntoRustString, _ initial_witness_vec_raw: RustVec<Int32>) -> Proof {
Proof(ptr: __swift_bridge__$prove_swift({ let rustString = circuit_bytecode.intoRustString(); rustString.isOwned = false; return rustString.ptr }(), { let val = initial_witness_vec_raw; val.isOwned = false; return val.ptr }()))
public func prove_swift<GenericIntoRustString: IntoRustString>(_ circuit_bytecode: GenericIntoRustString, _ initial_witness_vec_raw: RustVec<Int32>) -> Optional<Proof> {
{ let val = __swift_bridge__$prove_swift({ let rustString = circuit_bytecode.intoRustString(); rustString.isOwned = false; return rustString.ptr }(), { let val = initial_witness_vec_raw; val.isOwned = false; return val.ptr }()); if val != nil { return Proof(ptr: val!) } else { return nil } }()
}
public func verify_swift<GenericIntoRustString: IntoRustString>(_ circuit_bytecode: GenericIntoRustString, _ proof: Proof) -> Bool {
__swift_bridge__$verify_swift({ let rustString = circuit_bytecode.intoRustString(); rustString.isOwned = false; return rustString.ptr }(), {proof.isOwned = false; return proof.ptr;}())
public func verify_swift<GenericIntoRustString: IntoRustString>(_ circuit_bytecode: GenericIntoRustString, _ proof: Proof) -> Optional<Bool> {
__swift_bridge__$verify_swift({ let rustString = circuit_bytecode.intoRustString(); rustString.isOwned = false; return rustString.ptr }(), {proof.isOwned = false; return proof.ptr;}()).intoSwiftRepr()
}

public class Proof: ProofRefMut {
Expand Down
23 changes: 13 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ use noir_rs::{
mod ffi {
extern "Rust" {
type Proof;
fn prove_swift(circuit_bytecode: String, initial_witness_vec_raw: Vec<i32>) -> Proof;
fn verify_swift(circuit_bytecode: String, proof: Proof) -> bool;
fn prove_swift(
circuit_bytecode: String,
initial_witness_vec_raw: Vec<i32>,
) -> Option<Proof>;
fn verify_swift(circuit_bytecode: String, proof: Proof) -> Option<bool>;
}
}

Expand All @@ -17,7 +20,7 @@ pub struct Proof {
pub verification_key: Vec<u8>,
}

pub fn prove_swift(circuit_bytecode: String, initial_witness_vec_raw: Vec<i32>) -> Proof {
pub fn prove_swift(circuit_bytecode: String, initial_witness_vec_raw: Vec<i32>) -> Option<Proof> {
let initial_witness_vec: Vec<FieldElement> = initial_witness_vec_raw
.into_iter()
.map(|f| f as i128)
Expand All @@ -28,15 +31,15 @@ pub fn prove_swift(circuit_bytecode: String, initial_witness_vec_raw: Vec<i32>)
initial_witness.insert(Witness(i as u32 + 1), witness);
}

let (proof, verification_key) = prove(circuit_bytecode, initial_witness).unwrap();
Proof {
let (proof, verification_key) = prove(circuit_bytecode, initial_witness).ok()?;
Some(Proof {
proof,
verification_key,
}
})
}

pub fn verify_swift(circuit_bytecode: String, proof: Proof) -> bool {
verify(circuit_bytecode, proof.proof, proof.verification_key).unwrap()
pub fn verify_swift(circuit_bytecode: String, proof: Proof) -> Option<bool> {
verify(circuit_bytecode, proof.proof, proof.verification_key).ok()
}

#[cfg(test)]
Expand All @@ -47,8 +50,8 @@ mod tests {

#[test]
fn test_prove_verify() {
let proof = prove_swift(String::from(BYTECODE), vec![1_i32, 10_i32]);
let verdict = verify_swift(String::from(BYTECODE), proof);
let proof = prove_swift(String::from(BYTECODE), vec![1_i32, 10_i32]).unwrap();
let verdict = verify_swift(String::from(BYTECODE), proof).unwrap();
assert!(verdict);
}
}
2 changes: 1 addition & 1 deletion swift/bridging-header.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef BridgingHeader_h
#define BridgingHeader_h

#include "../generated/noir_swift/noir_swift.h"
#include "../generated/SwiftBridgeCore.h"
#include "../generated/noir_swift/noir_swift.h"

#endif /* BridgingHeader_h */
2 changes: 1 addition & 1 deletion swift/build.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
swiftc -L ../target/debug/ -lnoir_swift -lbarretenberg -lstdc++ -lssl -lcrypto -import-objc-header bridging-header.h main.swift ../generated/noir_swift/noir_swift.swift ../generated/SwiftBridgeCore.swift -o main.run
swiftc -L . -lnoir_swift -lbarretenberg -lstdc++ -lssl -lcrypto -import-objc-header bridging-header.h main.swift ../generated/noir_swift/noir_swift.swift ../generated/SwiftBridgeCore.swift -o main.run
16 changes: 15 additions & 1 deletion swift/main.swift
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
print("hello")
let BYTECODE = "H4sIAAAAAAAA/7WTMRLEIAhFMYkp9ywgGrHbq6yz5v5H2JkdCyaxC9LgWDw+H9gBwMM91p7fPeOzIKdYjEeMLYdGTB8MpUrCmOohJJQkfYMwN4mSSy0ZC0VudKbCZ4cthqzVrsc/yw28dMZeWmrWerfBexnsxD6hJ7jUufr4GvyZFp8xpG0C14Pd8s/q29vPCBXypvmpDx7sD8opnfqIfsM1RNtxBQAA"

func testProveVerify() -> Bool {
let vec = RustVec<Int32>()
vec.push(value: 1)
vec.push(value: 2)

guard let proof = prove_swift(BYTECODE, vec) else {
return false
}

return verify_swift(BYTECODE, proof) ?? false
}

print(testProveVerify())
Loading