feat(rln): package rln w/ resources into a static lib (#118)

* feat(rln): package resources into lib

* fix(rln): use Path

* fix(rln): fmt

* fix(rln): trailing slash
This commit is contained in:
Aaryamann Challani 2023-03-07 18:15:06 +05:30 committed by GitHub
parent bf2aa16a71
commit c319f32a1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 43 deletions

View File

@ -6,6 +6,13 @@ on:
jobs:
linux:
strategy:
matrix:
target:
- x86_64-unknown-linux-gnu
# TODO: enable after https://github.com/rust-lang/cargo/issues/4133 is resolved
# - aarch64-unknown-linux-gnu
# - i686-unknown-linux-gnu
name: Linux build
runs-on: ubuntu-latest
steps:
@ -17,25 +24,32 @@ jobs:
profile: minimal
toolchain: stable
override: true
target: ${{ matrix.target }}
- name: Update git submodules
run: git submodule update --init --recursive
- name: cargo build
run: |
cargo build --release --workspace --exclude rln-wasm
cargo build --release --target ${{ matrix.target }} --workspace --exclude rln-wasm
mkdir release
cp target/release/librln* release/
tar -czvf linux-rln.tar.gz release/
cp target/${{ matrix.target }}/release/librln* release/
tar -czvf ${{ matrix.target }}-rln.tar.gz release/
- name: Upload archive artifact
uses: actions/upload-artifact@v2
with:
name: linux-archive
path: linux-rln.tar.gz
name: ${{ matrix.target }}-archive
path: ${{ matrix.target }}-rln.tar.gz
retention-days: 2
macos:
name: MacOS build
runs-on: macos-latest
strategy:
matrix:
target:
- x86_64-apple-darwin
# TODO: enable after https://github.com/rust-lang/cargo/issues/4133 is resolved
# - aarch64-apple-darwin
steps:
- name: Checkout sources
uses: actions/checkout@v2
@ -47,20 +61,21 @@ jobs:
profile: minimal
toolchain: stable
override: true
target: ${{ matrix.target }}
- name: Update git submodules
run: git submodule update --init --recursive
- name: cargo build
run: |
cargo build --release --workspace --exclude rln-wasm
cargo build --release --target ${{ matrix.target }} --workspace --exclude rln-wasm
mkdir release
cp target/release/librln* release/
tar -czvf macos-rln.tar.gz release/
cp target/${{ matrix.target }}/release/librln* release/
tar -czvf ${{ matrix.target }}-rln.tar.gz release/
- name: Upload archive artifact
uses: actions/upload-artifact@v2
with:
name: macos-archive
path: macos-rln.tar.gz
name: ${{ matrix.target }}-archive
path: ${{ matrix.target }}-rln.tar.gz
retention-days: 2
browser-rln-wasm:
@ -125,9 +140,7 @@ jobs:
--title 'Nightly build ("master" branch)' \
--generate-notes \
--notes-start-tag $start_tag \
linux-archive/linux-rln.tar.gz \
macos-archive/macos-rln.tar.gz \
browser-rln-wasm-archive/browser-rln-wasm.tar.gz
*-archive/*.tar.gz \
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -136,6 +149,4 @@ jobs:
with:
failOnError: false
name: |
linux-archive
macos-archive
browser-rln-wasm-archive
*-archive

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT OR Apache-2.0"
[lib]
crate-type = ["cdylib", "rlib", "staticlib"]
crate-type = ["rlib", "staticlib"]
# This flag disable cargo doctests, i.e. testing example code-snippets in documentation
doctest = false
@ -41,7 +41,9 @@ utils = { path = "../utils/", default-features = false }
pmtree = { git = "https://github.com/Rate-Limiting-Nullifier/pmtree", rev = "f6d1a1fecad72cd39e6808e78085091d541dc882", optional = true}
# serialization
serde_json = "=1.0.93"
serde_json = "1.0.48"
include_dir = "=0.7.3"
[dev-dependencies]
sled = "=0.34.7"

View File

@ -11,7 +11,6 @@ use cfg_if::cfg_if;
use color_eyre::{Report, Result};
use num_bigint::BigUint;
use serde_json::Value;
use std::fs::File;
use std::io::Cursor;
use std::path::Path;
use std::str::FromStr;
@ -22,11 +21,12 @@ cfg_if! {
use once_cell::sync::OnceCell;
use std::sync::Mutex;
use wasmer::{Module, Store};
use include_dir::{include_dir, Dir};
}
}
const ZKEY_FILENAME: &str = "rln_final.zkey";
const VK_FILENAME: &str = "verifying_key.json";
const VK_FILENAME: &str = "verification_key.json";
const WASM_FILENAME: &str = "rln.wasm";
// These parameters are used for tests
@ -34,11 +34,11 @@ const WASM_FILENAME: &str = "rln.wasm";
// Changing these parameters to other values than these defaults will cause zkSNARK proof verification to fail
pub const TEST_PARAMETERS_INDEX: usize = 2;
pub const TEST_TREE_HEIGHT: usize = [15, 19, 20][TEST_PARAMETERS_INDEX];
pub const TEST_RESOURCES_FOLDER: &str = [
"./resources/tree_height_15/",
"./resources/tree_height_19/",
"./resources/tree_height_20/",
][TEST_PARAMETERS_INDEX];
pub const TEST_RESOURCES_FOLDER: &str =
["tree_height_15", "tree_height_19", "tree_height_20"][TEST_PARAMETERS_INDEX];
#[cfg(not(target_arch = "wasm32"))]
static RESOURCES_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/resources");
// The following types define the pairing friendly elliptic curve, the underlying finite fields and groups default to this module
// Note that proofs are serialized assuming Fr to be 4x8 = 32 bytes in size. Hence, changing to a curve with different encoding will make proof verification to fail
@ -63,13 +63,14 @@ pub fn zkey_from_raw(zkey_data: &Vec<u8>) -> Result<(ProvingKey<Curve>, Constrai
}
// Loads the proving key
#[cfg(not(target_arch = "wasm32"))]
pub fn zkey_from_folder(
resources_folder: &str,
) -> Result<(ProvingKey<Curve>, ConstraintMatrices<Fr>)> {
let zkey_path = format!("{resources_folder}{ZKEY_FILENAME}");
if Path::new(&zkey_path).exists() {
let mut file = File::open(&zkey_path)?;
let proving_key_and_matrices = read_zkey(&mut file)?;
let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ZKEY_FILENAME));
if let Some(zkey) = zkey {
let mut c = Cursor::new(zkey.contents());
let proving_key_and_matrices = read_zkey(&mut c)?;
Ok(proving_key_and_matrices)
} else {
Err(Report::msg("No proving key found!"))
@ -93,15 +94,18 @@ pub fn vk_from_raw(vk_data: &Vec<u8>, zkey_data: &Vec<u8>) -> Result<VerifyingKe
}
// Loads the verification key
#[cfg(not(target_arch = "wasm32"))]
pub fn vk_from_folder(resources_folder: &str) -> Result<VerifyingKey<Curve>> {
let vk_path = format!("{resources_folder}{VK_FILENAME}");
let zkey_path = format!("{resources_folder}{ZKEY_FILENAME}");
let vk = RESOURCES_DIR.get_file(Path::new(resources_folder).join(VK_FILENAME));
let zkey = RESOURCES_DIR.get_file(Path::new(resources_folder).join(ZKEY_FILENAME));
let verifying_key: VerifyingKey<Curve>;
if Path::new(&vk_path).exists() {
vk_from_json(&vk_path)
} else if Path::new(&zkey_path).exists() {
if let Some(vk) = vk {
verifying_key = vk_from_json(vk.contents_utf8().ok_or(Report::msg(
"Could not read verification key from JSON file!",
))?)?;
Ok(verifying_key)
} else if let Some(_zkey) = zkey {
let (proving_key, _matrices) = zkey_from_folder(resources_folder)?;
verifying_key = proving_key.vk;
Ok(verifying_key)
@ -128,9 +132,14 @@ pub fn circom_from_raw(wasm_buffer: Vec<u8>) -> Result<&'static Mutex<WitnessCal
#[cfg(not(target_arch = "wasm32"))]
pub fn circom_from_folder(resources_folder: &str) -> Result<&'static Mutex<WitnessCalculator>> {
// We read the wasm file
let wasm_path = format!("{resources_folder}{WASM_FILENAME}");
let wasm_buffer = std::fs::read(wasm_path)?;
circom_from_raw(wasm_buffer)
let wasm = RESOURCES_DIR.get_file(Path::new(resources_folder).join(WASM_FILENAME));
if let Some(wasm) = wasm {
let wasm_buffer = wasm.contents();
circom_from_raw(wasm_buffer.to_vec())
} else {
Err(Report::msg("No wasm file found!"))
}
}
// The following function implementations are taken/adapted from https://github.com/gakonst/ark-circom/blob/1732e15d6313fe176b0b1abb858ac9e095d0dbd7/src/zkey.rs
@ -231,10 +240,8 @@ fn to_verifying_key(json: serde_json::Value) -> Result<VerifyingKey<Curve>> {
}
// Computes the verification key from its JSON serialization
fn vk_from_json(vk_path: &str) -> Result<VerifyingKey<Curve>> {
let json = std::fs::read_to_string(vk_path)?;
let json: Value = serde_json::from_str(&json)?;
fn vk_from_json(vk: &str) -> Result<VerifyingKey<Curve>> {
let json: Value = serde_json::from_str(vk)?;
to_verifying_key(json)
}
@ -247,6 +254,7 @@ fn vk_from_vector(vk: &[u8]) -> Result<VerifyingKey<Curve>> {
}
// Checks verification key to be correct with respect to proving key
#[cfg(not(target_arch = "wasm32"))]
pub fn check_vk_from_zkey(
resources_folder: &str,
verifying_key: VerifyingKey<Curve>,

View File

@ -61,7 +61,7 @@ impl RLN<'_> {
/// use std::io::Cursor;
///
/// let tree_height = 20;
/// let resources = Cursor::new("./resources/tree_height_20/");
/// let resources = Cursor::new("tree_height_20");
///
/// // We create a new RLN instance
/// let mut rln = RLN::new(tree_height, resources);