mirror of
https://github.com/logos-blockchain/logos-blockchain-circuits.git
synced 2026-05-18 15:29:26 +00:00
feat: Circuits as libraries (#16)
This commit is contained in:
parent
d6cf41f665
commit
64ec496067
34
.cargo-deny.toml
Normal file
34
.cargo-deny.toml
Normal file
@ -0,0 +1,34 @@
|
||||
# Config file reference can be found at https://embarkstudios.github.io/cargo-deny/checks/cfg.html.
|
||||
|
||||
[graph]
|
||||
all-features = true
|
||||
exclude-dev = true
|
||||
no-default-features = true
|
||||
|
||||
[advisories]
|
||||
ignore = []
|
||||
unused-ignored-advisory = "deny"
|
||||
yanked = "deny"
|
||||
|
||||
[bans]
|
||||
allow-wildcard-paths = false
|
||||
multiple-versions = "allow"
|
||||
|
||||
[licenses]
|
||||
allow = [
|
||||
"Apache-2.0 WITH LLVM-exception",
|
||||
"Apache-2.0",
|
||||
"BSD-3-Clause",
|
||||
"CDLA-Permissive-2.0",
|
||||
"ISC",
|
||||
"MIT",
|
||||
"MPL-2.0",
|
||||
"Unicode-3.0",
|
||||
"Zlib",
|
||||
]
|
||||
private = { ignore = false }
|
||||
unused-allowed-license = "deny"
|
||||
|
||||
[sources]
|
||||
unknown-git = "deny"
|
||||
unknown-registry = "deny"
|
||||
@ -9,7 +9,7 @@ inputs:
|
||||
description: "The name of the Circom circuit to compile."
|
||||
required: true
|
||||
circuit-name-binary:
|
||||
description: "The final name of the compiled binary. The name should be extensionless."
|
||||
description: "The name used for artifact labelling. Should match the circuit's canonical name (e.g. pol, poq)."
|
||||
required: true
|
||||
circuit-path:
|
||||
description: "The path to the Circom circuit file relative to the repository root."
|
||||
@ -45,10 +45,12 @@ runs:
|
||||
CIRCUIT_FILENAME="$(basename ${CIRCUIT_PATH})"
|
||||
CIRCUIT_FILESTEM="${CIRCUIT_FILENAME%.circom}"
|
||||
CIRCUIT_CPP_DIRNAME="${CIRCUIT_FILESTEM}_cpp"
|
||||
|
||||
compiled_binary_name="${CIRCUIT_FILESTEM}"
|
||||
if [ "${OS}" = "windows" ]; then
|
||||
compiled_binary_name="${compiled_binary_name}.exe"
|
||||
LIB_EXT=".lib"
|
||||
LIB_PREFIX=""
|
||||
else
|
||||
LIB_EXT=".a"
|
||||
LIB_PREFIX="lib"
|
||||
fi
|
||||
|
||||
{
|
||||
@ -59,7 +61,7 @@ runs:
|
||||
echo "CIRCUIT_CPP_PATH=${CIRCUIT_DIRECTORY}/${CIRCUIT_CPP_DIRNAME}"
|
||||
echo "WITNESS_GENERATOR_RESOURCES_PATH=${RESOURCES_PATH}/witness-generator"
|
||||
echo "BUNDLE_TRIPLET=${BUNDLE_TRIPLET}"
|
||||
echo "COMPILED_BINARY_NAME=${compiled_binary_name}"
|
||||
echo "LIB_NAME=${LIB_PREFIX}${CIRCUIT_FILESTEM}${LIB_EXT}"
|
||||
} >> "${GITHUB_OUTPUT}"
|
||||
|
||||
- name: Generate ${{ inputs.circuit-name-display }}
|
||||
@ -69,6 +71,19 @@ runs:
|
||||
CIRCUIT_FILENAME: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILENAME }}
|
||||
run: circom --c --r1cs --no_asm --O2 "${CIRCUIT_FILENAME}"
|
||||
|
||||
- name: Copy ${{ inputs.circuit-name-display }} FFI Sources
|
||||
shell: bash
|
||||
env:
|
||||
SOURCES_ROOT: ${{ github.workspace }}/src
|
||||
CIRCUIT_CPP_PATH: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
CIRCUIT_FILESTEM: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
run: |
|
||||
cp -r "${SOURCES_ROOT}/${CIRCUIT_FILESTEM}" "${CIRCUIT_CPP_PATH}/${CIRCUIT_FILESTEM}"
|
||||
cp "${SOURCES_ROOT}/circom_adapter.cpp" "${CIRCUIT_CPP_PATH}/circom_adapter.cpp"
|
||||
cp "${SOURCES_ROOT}/circom_adapter.hpp" "${CIRCUIT_CPP_PATH}/circom_adapter.hpp"
|
||||
cp "${SOURCES_ROOT}/circom_fwd.hpp" "${CIRCUIT_CPP_PATH}/circom_fwd.hpp"
|
||||
cp "${SOURCES_ROOT}/types.hpp" "${CIRCUIT_CPP_PATH}/types.hpp"
|
||||
|
||||
# TODO: Instead of replace, make a fork that generates the appropriate Makefile
|
||||
- name: Replace ${{ inputs.circuit-name-display }}'s Makefile
|
||||
shell: bash
|
||||
@ -77,6 +92,17 @@ runs:
|
||||
CIRCUIT_CPP_PATH: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
run: cp "${WITNESS_GENERATOR_RESOURCES_PATH}/Makefile" "${CIRCUIT_CPP_PATH}/Makefile"
|
||||
|
||||
# circom-generated main() has no return on the success path; patch it before -O3 turns it into an infinite loop
|
||||
- name: Patch ${{ inputs.circuit-name-display }} Missing Return
|
||||
shell: bash
|
||||
env:
|
||||
CIRCUIT_CPP_PATH: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: |
|
||||
SED_I="sed -i"
|
||||
if [ "$OS" = "macos" ]; then SED_I="sed -i ''"; fi
|
||||
$SED_I ':a;N;$!ba;s/\n}\n\n*$/\n return 0;\n}/' "${CIRCUIT_CPP_PATH}/main.cpp"
|
||||
|
||||
# TODO: Instead of insertion, make a fork that includes the appropriate patch (or the actual fix)
|
||||
- name: Patch MacOS GMP
|
||||
shell: bash
|
||||
@ -94,7 +120,7 @@ runs:
|
||||
env:
|
||||
CIRCUIT_FILESTEM: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: make PROJECT="${CIRCUIT_FILESTEM}" "${OS}"
|
||||
run: make PROJECT="${CIRCUIT_FILESTEM}" "${OS}-lib"
|
||||
|
||||
- name: Compile ${{ inputs.circuit-name-display }}
|
||||
if: ${{ inputs.os == 'windows' }}
|
||||
@ -103,12 +129,26 @@ runs:
|
||||
env:
|
||||
CIRCUIT_FILESTEM: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
OS: ${{ inputs.os }}
|
||||
run: make PROJECT="${CIRCUIT_FILESTEM}" "${OS}"
|
||||
run: make PROJECT="${CIRCUIT_FILESTEM}" "${OS}-lib"
|
||||
|
||||
- name: Stage ${{ inputs.circuit-name-display }} Headers
|
||||
shell: bash
|
||||
env:
|
||||
CIRCUIT_CPP_PATH: ${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}
|
||||
CIRCUIT_FILESTEM: ${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}
|
||||
run: |
|
||||
mkdir -p "${CIRCUIT_CPP_PATH}/include"
|
||||
mv "${CIRCUIT_CPP_PATH}/calcwit.hpp" "${CIRCUIT_CPP_PATH}/include/"
|
||||
mv "${CIRCUIT_CPP_PATH}/circom.hpp" "${CIRCUIT_CPP_PATH}/include/"
|
||||
mv "${CIRCUIT_CPP_PATH}/fr.hpp" "${CIRCUIT_CPP_PATH}/include/"
|
||||
mv "${CIRCUIT_CPP_PATH}/${CIRCUIT_FILESTEM}/ffi.hpp" "${CIRCUIT_CPP_PATH}/include/"
|
||||
mv "${CIRCUIT_CPP_PATH}/types.hpp" "${CIRCUIT_CPP_PATH}/include/"
|
||||
|
||||
- name: Upload ${{ inputs.circuit-name-display }}
|
||||
uses: actions/upload-artifact@de65e23aa2b7e23d713bb51fbfcb6d502f8667d8
|
||||
with:
|
||||
name: ${{ inputs.circuit-name-binary }}-${{ inputs.version }}-${{ inputs.os }}-${{ inputs.arch }}
|
||||
path: |
|
||||
${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}/${{ steps.parse-circuit-path.outputs.COMPILED_BINARY_NAME }}
|
||||
${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}/${{ steps.parse-circuit-path.outputs.LIB_NAME }}
|
||||
${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}/${{ steps.parse-circuit-path.outputs.CIRCUIT_FILESTEM }}.dat
|
||||
${{ steps.parse-circuit-path.outputs.CIRCUIT_CPP_PATH }}/include
|
||||
|
||||
39
.github/resources/witness-generator/Makefile
vendored
39
.github/resources/witness-generator/Makefile
vendored
@ -1,4 +1,4 @@
|
||||
.PHONY: linux macos windows build clean
|
||||
.PHONY: linux macos windows linux-lib macos-lib windows-lib build clean
|
||||
|
||||
# ---- Arguments ----
|
||||
ifndef PROJECT
|
||||
@ -7,11 +7,23 @@ endif
|
||||
|
||||
# ---- Common ----
|
||||
CXX := g++
|
||||
CXXFLAGS_COMMON := -std=c++11 -O3 -I. -Wno-address-of-packed-member
|
||||
SRCS := main.cpp calcwit.cpp fr.cpp $(PROJECT).cpp
|
||||
OBJS := $(SRCS:.cpp=.o)
|
||||
DEPS_HPP := circom.hpp calcwit.hpp fr.hpp
|
||||
CXXFLAGS_COMMON := -std=c++11 -O3 -I. -Wno-address-of-packed-member -Dmain=circom_main
|
||||
COMMON_SRCS := main.cpp calcwit.cpp fr.cpp $(PROJECT).cpp
|
||||
COMMON_OBJS := $(COMMON_SRCS:.cpp=.o)
|
||||
LIB_ONLY_SRCS := $(PROJECT)/ffi.cpp circom_adapter.cpp
|
||||
LIB_ONLY_OBJS := $(LIB_ONLY_SRCS:.cpp=.o)
|
||||
LIB_SRCS := $(COMMON_SRCS) $(LIB_ONLY_SRCS)
|
||||
LIB_OBJS := $(COMMON_OBJS) $(LIB_ONLY_OBJS)
|
||||
DEPS_HPP := circom.hpp calcwit.hpp fr.hpp types.hpp $(PROJECT)/ffi.hpp
|
||||
BIN := $(PROJECT)
|
||||
ifeq ($(OS),windows)
|
||||
LIB_EXT := .lib
|
||||
LIB_PREFIX :=
|
||||
else
|
||||
LIB_EXT := .a
|
||||
LIB_PREFIX := lib
|
||||
endif
|
||||
LIB := $(LIB_PREFIX)$(PROJECT)$(LIB_EXT)
|
||||
|
||||
# ---- Linux (x86_64 and aarch64) ----
|
||||
linux: CXXFLAGS=$(CXXFLAGS_COMMON)
|
||||
@ -19,25 +31,36 @@ linux: LDFLAGS=-static
|
||||
linux: LDLIBS=-lgmp
|
||||
linux: $(BIN)
|
||||
|
||||
linux-lib: CXXFLAGS=$(CXXFLAGS_COMMON) -fPIC
|
||||
linux-lib: $(LIB)
|
||||
|
||||
# ---- macOS ----
|
||||
macos: CXXFLAGS=$(CXXFLAGS_COMMON) -I/opt/homebrew/include -include gmp_patch.hpp
|
||||
macos: LDFLAGS=-Wl,-search_paths_first -Wl,-dead_strip
|
||||
macos: LDLIBS=/opt/homebrew/lib/libgmp.a
|
||||
macos: $(BIN)
|
||||
|
||||
macos-lib: CXXFLAGS=$(CXXFLAGS_COMMON) -fPIC -I/opt/homebrew/include -include gmp_patch.hpp
|
||||
macos-lib: $(LIB)
|
||||
|
||||
# ---- Windows (MinGW) ----
|
||||
windows: CXXFLAGS=$(CXXFLAGS_COMMON) -I/include -Duint="unsigned int"
|
||||
windows: LDFLAGS=-static
|
||||
windows: LDLIBS=-L/lib -lgmp -lmman
|
||||
windows: $(BIN)
|
||||
|
||||
windows-lib: CXXFLAGS=$(CXXFLAGS_COMMON) -fPIC -I/include -Duint="unsigned int"
|
||||
windows-lib: $(LIB)
|
||||
|
||||
# ---- Rules ----
|
||||
$(BIN): $(OBJS)
|
||||
$(BIN): $(COMMON_OBJS)
|
||||
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
|
||||
$(LIB): $(LIB_OBJS)
|
||||
ar rcs $@ $^
|
||||
|
||||
%.o: %.cpp $(DEPS_HPP)
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) $(BIN)
|
||||
|
||||
rm -f $(COMMON_OBJS) $(LIB_ONLY_OBJS) $(BIN) $(LIB)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
name: Build Circuits
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -13,6 +13,9 @@ on:
|
||||
description: "Tag to release. Must follow the format of 'vX.Y.Z'."
|
||||
required: true
|
||||
|
||||
env:
|
||||
CIRCOM_TAG: v2.2.2
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
name: Configure Environment
|
||||
@ -49,6 +52,27 @@ jobs:
|
||||
echo "tag=$TAG" >> $GITHUB_OUTPUT
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 # v4.2.2
|
||||
with:
|
||||
sparse-checkout: rust/Cargo.toml
|
||||
sparse-checkout-cone-mode: false
|
||||
|
||||
- name: Verify Cargo version
|
||||
env:
|
||||
VERSION: ${{ steps.define-version.outputs.version }}
|
||||
run: |
|
||||
if [[ "$VERSION" =~ ^v0\.0\.0-pr ]]; then
|
||||
echo "Skipping version check for PR build."
|
||||
exit 0
|
||||
fi
|
||||
CARGO_VERSION=$(grep '^version = ' rust/Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
|
||||
if [ "$CARGO_VERSION" != "${VERSION#v}" ]; then
|
||||
echo "Version mismatch: Cargo.toml has '$CARGO_VERSION' but tag is '$VERSION'."
|
||||
exit 1
|
||||
fi
|
||||
echo "Version check passed: $CARGO_VERSION"
|
||||
|
||||
generate-proving-keys:
|
||||
name: Generate ${{ matrix.circuit.display }} Proving Key
|
||||
runs-on: ubuntu-latest
|
||||
@ -66,8 +90,8 @@ jobs:
|
||||
display: PoQ
|
||||
file: poq.circom
|
||||
dir: blend
|
||||
- name: zksign
|
||||
display: ZKSign
|
||||
- name: signature
|
||||
display: Signature
|
||||
file: signature.circom
|
||||
dir: mantle
|
||||
- name: poc
|
||||
@ -79,33 +103,30 @@ jobs:
|
||||
PTAU_URL: "https://storage.googleapis.com/zkevm/ptau/powersOfTau28_hez_final_17.ptau"
|
||||
PTAU_FILE: "powersOfTau28_hez_final_17.ptau"
|
||||
steps:
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone --branch ${{ env.CIRCOM_TAG }} --depth 1 https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install snarkjs
|
||||
run: npm install -g snarkjs@latest
|
||||
run: npm install -g snarkjs@0.7.6
|
||||
|
||||
- name: Cache Powers of Tau
|
||||
id: cache-ptau
|
||||
@ -126,6 +147,7 @@ jobs:
|
||||
cd ${{ matrix.circuit.dir }}
|
||||
circom --r1cs --O2 ${{ matrix.circuit.file }}
|
||||
snarkjs groth16 setup ${CIRCUIT_NAME}.r1cs ../${{ env.PTAU_FILE }} ${{ matrix.circuit.name }}-0.zkey
|
||||
# Single-contributor trusted setup: A proper MPC ceremony is required before production (see issue #17).
|
||||
head -c 32 /dev/urandom | xxd -p -c 256 | snarkjs zkey contribute ${{ matrix.circuit.name }}-0.zkey ${{ matrix.circuit.name }}.zkey --name="RELEASE" -v
|
||||
snarkjs zkey export verificationkey ${{ matrix.circuit.name }}.zkey ${{ matrix.circuit.name }}_verification_key.json
|
||||
env:
|
||||
@ -140,7 +162,7 @@ jobs:
|
||||
${{ matrix.circuit.dir }}/${{ matrix.circuit.name }}_verification_key.json
|
||||
|
||||
build-linux:
|
||||
name: Build Linux Binaries (Native)
|
||||
name: Build Linux Libraries (Native)
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
@ -150,26 +172,23 @@ jobs:
|
||||
OS: linux
|
||||
ARCH: x86_64
|
||||
steps:
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone --branch ${{ env.CIRCOM_TAG }} --depth 1 https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Setup Dependencies
|
||||
working-directory: rapidsnark
|
||||
run: sudo apt update -y
|
||||
@ -262,11 +281,11 @@ jobs:
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile ZKSign Witness Generator
|
||||
- name: Compile Signature Witness Generator
|
||||
uses: ./.github/actions/compile-witness-generator
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-name-display: "Signature"
|
||||
circuit-name-binary: "signature"
|
||||
circuit-path: "mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
@ -294,11 +313,11 @@ jobs:
|
||||
name: poq-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/poq-artifact
|
||||
|
||||
- name: Download ZKSign Witness Generator
|
||||
- name: Download Signature Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: zksign-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/zksign-artifact
|
||||
name: signature-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/signature-artifact
|
||||
|
||||
- name: Download PoC Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
@ -329,7 +348,7 @@ jobs:
|
||||
BUNDLE_NAME: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
run: |
|
||||
# Create the bundle directory structure
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,zksign,poc}
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,signature,poc}
|
||||
|
||||
# Create VERSION file
|
||||
echo "${{ env.VERSION }}" > "${BUNDLE_NAME}/VERSION"
|
||||
@ -342,29 +361,27 @@ jobs:
|
||||
chmod +x "${BUNDLE_NAME}/prover"
|
||||
chmod +x "${BUNDLE_NAME}/verifier"
|
||||
|
||||
# Move witness generators into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/pol "${BUNDLE_NAME}/pol/witness_generator"
|
||||
# Move witness libraries into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/libpol.a "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/pol-artifact/pol.dat "${BUNDLE_NAME}/pol/witness_generator.dat"
|
||||
mv witness-generators/poq-artifact/poq "${BUNDLE_NAME}/poq/witness_generator"
|
||||
cp -r witness-generators/pol-artifact/include "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/poq-artifact/libpoq.a "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/poq-artifact/poq.dat "${BUNDLE_NAME}/poq/witness_generator.dat"
|
||||
mv witness-generators/zksign-artifact/signature "${BUNDLE_NAME}/zksign/witness_generator"
|
||||
mv witness-generators/zksign-artifact/signature.dat "${BUNDLE_NAME}/zksign/witness_generator.dat"
|
||||
mv witness-generators/poc-artifact/poc "${BUNDLE_NAME}/poc/witness_generator"
|
||||
cp -r witness-generators/poq-artifact/include "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/signature-artifact/libsignature.a "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/signature-artifact/signature.dat "${BUNDLE_NAME}/signature/witness_generator.dat"
|
||||
cp -r witness-generators/signature-artifact/include "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/poc-artifact/libpoc.a "${BUNDLE_NAME}/poc/"
|
||||
mv witness-generators/poc-artifact/poc.dat "${BUNDLE_NAME}/poc/witness_generator.dat"
|
||||
|
||||
# Restore execute permissions on witness generators
|
||||
chmod +x "${BUNDLE_NAME}/pol/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/poq/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/zksign/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/poc/witness_generator"
|
||||
cp -r witness-generators/poc-artifact/include "${BUNDLE_NAME}/poc/"
|
||||
|
||||
# Copy proving keys and verification keys into each circuit directory
|
||||
cp proving-keys/pol-proving-key/pol.zkey "${BUNDLE_NAME}/pol/proving_key.zkey"
|
||||
cp proving-keys/pol-proving-key/pol_verification_key.json "${BUNDLE_NAME}/pol/verification_key.json"
|
||||
cp proving-keys/poq-proving-key/poq.zkey "${BUNDLE_NAME}/poq/proving_key.zkey"
|
||||
cp proving-keys/poq-proving-key/poq_verification_key.json "${BUNDLE_NAME}/poq/verification_key.json"
|
||||
cp proving-keys/zksign-proving-key/zksign.zkey "${BUNDLE_NAME}/zksign/proving_key.zkey"
|
||||
cp proving-keys/zksign-proving-key/zksign_verification_key.json "${BUNDLE_NAME}/zksign/verification_key.json"
|
||||
cp proving-keys/signature-proving-key/signature.zkey "${BUNDLE_NAME}/signature/proving_key.zkey"
|
||||
cp proving-keys/signature-proving-key/signature_verification_key.json "${BUNDLE_NAME}/signature/verification_key.json"
|
||||
cp proving-keys/poc-proving-key/poc.zkey "${BUNDLE_NAME}/poc/proving_key.zkey"
|
||||
cp proving-keys/poc-proving-key/poc_verification_key.json "${BUNDLE_NAME}/poc/verification_key.json"
|
||||
|
||||
@ -378,7 +395,7 @@ jobs:
|
||||
path: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
build-linux-aarch64:
|
||||
name: Build Linux aarch64 Binaries (Native for RPI5)
|
||||
name: Build Linux aarch64 Libraries (Native for RPI5)
|
||||
runs-on: ubuntu-22.04-arm
|
||||
needs:
|
||||
- setup
|
||||
@ -388,26 +405,23 @@ jobs:
|
||||
OS: linux
|
||||
ARCH: aarch64
|
||||
steps:
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone --branch ${{ env.CIRCOM_TAG }} --depth 1 https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Setup Dependencies
|
||||
working-directory: rapidsnark
|
||||
run: sudo apt update -y
|
||||
@ -502,11 +516,11 @@ jobs:
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile ZKSign Witness Generator
|
||||
- name: Compile Signature Witness Generator
|
||||
uses: ./.github/actions/compile-witness-generator
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-name-display: "Signature"
|
||||
circuit-name-binary: "signature"
|
||||
circuit-path: "mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
@ -534,11 +548,11 @@ jobs:
|
||||
name: poq-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/poq-artifact
|
||||
|
||||
- name: Download ZKSign Witness Generator
|
||||
- name: Download Signature Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: zksign-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/zksign-artifact
|
||||
name: signature-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/signature-artifact
|
||||
|
||||
- name: Download PoC Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
@ -569,7 +583,7 @@ jobs:
|
||||
BUNDLE_NAME: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
run: |
|
||||
# Create the bundle directory structure
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,zksign,poc}
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,signature,poc}
|
||||
|
||||
# Create VERSION file
|
||||
echo "${{ env.VERSION }}" > "${BUNDLE_NAME}/VERSION"
|
||||
@ -582,29 +596,27 @@ jobs:
|
||||
chmod +x "${BUNDLE_NAME}/prover"
|
||||
chmod +x "${BUNDLE_NAME}/verifier"
|
||||
|
||||
# Move witness generators into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/pol "${BUNDLE_NAME}/pol/witness_generator"
|
||||
# Move witness libraries into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/libpol.a "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/pol-artifact/pol.dat "${BUNDLE_NAME}/pol/witness_generator.dat"
|
||||
mv witness-generators/poq-artifact/poq "${BUNDLE_NAME}/poq/witness_generator"
|
||||
cp -r witness-generators/pol-artifact/include "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/poq-artifact/libpoq.a "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/poq-artifact/poq.dat "${BUNDLE_NAME}/poq/witness_generator.dat"
|
||||
mv witness-generators/zksign-artifact/signature "${BUNDLE_NAME}/zksign/witness_generator"
|
||||
mv witness-generators/zksign-artifact/signature.dat "${BUNDLE_NAME}/zksign/witness_generator.dat"
|
||||
mv witness-generators/poc-artifact/poc "${BUNDLE_NAME}/poc/witness_generator"
|
||||
cp -r witness-generators/poq-artifact/include "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/signature-artifact/libsignature.a "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/signature-artifact/signature.dat "${BUNDLE_NAME}/signature/witness_generator.dat"
|
||||
cp -r witness-generators/signature-artifact/include "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/poc-artifact/libpoc.a "${BUNDLE_NAME}/poc/"
|
||||
mv witness-generators/poc-artifact/poc.dat "${BUNDLE_NAME}/poc/witness_generator.dat"
|
||||
|
||||
# Restore execute permissions on witness generators
|
||||
chmod +x "${BUNDLE_NAME}/pol/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/poq/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/zksign/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/poc/witness_generator"
|
||||
cp -r witness-generators/poc-artifact/include "${BUNDLE_NAME}/poc/"
|
||||
|
||||
# Copy proving keys and verification keys into each circuit directory
|
||||
cp proving-keys/pol-proving-key/pol.zkey "${BUNDLE_NAME}/pol/proving_key.zkey"
|
||||
cp proving-keys/pol-proving-key/pol_verification_key.json "${BUNDLE_NAME}/pol/verification_key.json"
|
||||
cp proving-keys/poq-proving-key/poq.zkey "${BUNDLE_NAME}/poq/proving_key.zkey"
|
||||
cp proving-keys/poq-proving-key/poq_verification_key.json "${BUNDLE_NAME}/poq/verification_key.json"
|
||||
cp proving-keys/zksign-proving-key/zksign.zkey "${BUNDLE_NAME}/zksign/proving_key.zkey"
|
||||
cp proving-keys/zksign-proving-key/zksign_verification_key.json "${BUNDLE_NAME}/zksign/verification_key.json"
|
||||
cp proving-keys/signature-proving-key/signature.zkey "${BUNDLE_NAME}/signature/proving_key.zkey"
|
||||
cp proving-keys/signature-proving-key/signature_verification_key.json "${BUNDLE_NAME}/signature/verification_key.json"
|
||||
cp proving-keys/poc-proving-key/poc.zkey "${BUNDLE_NAME}/poc/proving_key.zkey"
|
||||
cp proving-keys/poc-proving-key/poc_verification_key.json "${BUNDLE_NAME}/poc/verification_key.json"
|
||||
|
||||
@ -618,7 +630,7 @@ jobs:
|
||||
path: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
build-windows:
|
||||
name: Build Windows Binaries (Native)
|
||||
name: Build Windows Libraries (Native)
|
||||
runs-on: windows-latest
|
||||
needs:
|
||||
- setup
|
||||
@ -638,26 +650,23 @@ jobs:
|
||||
make
|
||||
git
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
$env:RUSTFLAGS="-A dead_code"; cargo build --release
|
||||
$env:RUSTFLAGS="-A dead_code"; cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone --branch ${{ env.CIRCOM_TAG }} --depth 1 https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
$env:RUSTFLAGS="-A dead_code"; cargo build --release
|
||||
$env:RUSTFLAGS="-A dead_code"; cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Install Dependencies [Witness Generator]
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
@ -780,11 +789,11 @@ jobs:
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile ZKSign Witness Generator
|
||||
- name: Compile Signature Witness Generator
|
||||
uses: ./.github/actions/compile-witness-generator
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-name-display: "Signature"
|
||||
circuit-name-binary: "signature"
|
||||
circuit-path: "mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
@ -812,11 +821,11 @@ jobs:
|
||||
name: poq-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/poq-artifact
|
||||
|
||||
- name: Download ZKSign Witness Generator
|
||||
- name: Download Signature Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: zksign-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/zksign-artifact
|
||||
name: signature-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/signature-artifact
|
||||
|
||||
- name: Download PoC Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
@ -848,7 +857,7 @@ jobs:
|
||||
BUNDLE_NAME: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
run: |
|
||||
# Create the bundle directory structure
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,zksign,poc}
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,signature,poc}
|
||||
|
||||
# Create VERSION file
|
||||
echo "${{ env.VERSION }}" > "${BUNDLE_NAME}/VERSION"
|
||||
@ -859,23 +868,27 @@ jobs:
|
||||
mv prover-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/prover/prover.exe "${BUNDLE_NAME}/prover.exe"
|
||||
mv verifier-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/verifier/verifier.exe "${BUNDLE_NAME}/verifier.exe"
|
||||
|
||||
# Move witness generators into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/pol.exe "${BUNDLE_NAME}/pol/witness_generator.exe"
|
||||
# Move witness libraries into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/pol.lib "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/pol-artifact/pol.dat "${BUNDLE_NAME}/pol/witness_generator.dat"
|
||||
mv witness-generators/poq-artifact/poq.exe "${BUNDLE_NAME}/poq/witness_generator.exe"
|
||||
cp -r witness-generators/pol-artifact/include "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/poq-artifact/poq.lib "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/poq-artifact/poq.dat "${BUNDLE_NAME}/poq/witness_generator.dat"
|
||||
mv witness-generators/zksign-artifact/signature.exe "${BUNDLE_NAME}/zksign/witness_generator.exe"
|
||||
mv witness-generators/zksign-artifact/signature.dat "${BUNDLE_NAME}/zksign/witness_generator.dat"
|
||||
mv witness-generators/poc-artifact/poc.exe "${BUNDLE_NAME}/poc/witness_generator.exe"
|
||||
cp -r witness-generators/poq-artifact/include "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/signature-artifact/signature.lib "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/signature-artifact/signature.dat "${BUNDLE_NAME}/signature/witness_generator.dat"
|
||||
cp -r witness-generators/signature-artifact/include "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/poc-artifact/poc.lib "${BUNDLE_NAME}/poc/"
|
||||
mv witness-generators/poc-artifact/poc.dat "${BUNDLE_NAME}/poc/witness_generator.dat"
|
||||
cp -r witness-generators/poc-artifact/include "${BUNDLE_NAME}/poc/"
|
||||
|
||||
# Copy proving keys and verification keys into each circuit directory
|
||||
cp proving-keys/pol-proving-key/pol.zkey "${BUNDLE_NAME}/pol/proving_key.zkey"
|
||||
cp proving-keys/pol-proving-key/pol_verification_key.json "${BUNDLE_NAME}/pol/verification_key.json"
|
||||
cp proving-keys/poq-proving-key/poq.zkey "${BUNDLE_NAME}/poq/proving_key.zkey"
|
||||
cp proving-keys/poq-proving-key/poq_verification_key.json "${BUNDLE_NAME}/poq/verification_key.json"
|
||||
cp proving-keys/zksign-proving-key/zksign.zkey "${BUNDLE_NAME}/zksign/proving_key.zkey"
|
||||
cp proving-keys/zksign-proving-key/zksign_verification_key.json "${BUNDLE_NAME}/zksign/verification_key.json"
|
||||
cp proving-keys/signature-proving-key/signature.zkey "${BUNDLE_NAME}/signature/proving_key.zkey"
|
||||
cp proving-keys/signature-proving-key/signature_verification_key.json "${BUNDLE_NAME}/signature/verification_key.json"
|
||||
cp proving-keys/poc-proving-key/poc.zkey "${BUNDLE_NAME}/poc/proving_key.zkey"
|
||||
cp proving-keys/poc-proving-key/poc_verification_key.json "${BUNDLE_NAME}/poc/verification_key.json"
|
||||
|
||||
@ -889,7 +902,7 @@ jobs:
|
||||
path: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
build-macos:
|
||||
name: Build MacOS Binaries (Native)
|
||||
name: Build MacOS Libraries (Native)
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- setup
|
||||
@ -899,31 +912,28 @@ jobs:
|
||||
ARCH: aarch64
|
||||
OS: macos
|
||||
steps:
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48
|
||||
with:
|
||||
toolchain: stable
|
||||
cache: false
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Initialise Submodules
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Circom
|
||||
run: |
|
||||
git clone --branch ${{ env.CIRCOM_TAG }} --depth 1 https://github.com/iden3/circom.git
|
||||
cd circom
|
||||
RUSTFLAGS="-A dead_code" cargo build --release
|
||||
RUSTFLAGS="-A dead_code" cargo install --path circom
|
||||
circom --version
|
||||
|
||||
- name: Setup Dependencies
|
||||
run: mkdir include
|
||||
|
||||
- name: Install Dependencies [Witness Generator]
|
||||
run: brew install nlohmann-json
|
||||
run: brew install nlohmann-json binutils
|
||||
|
||||
- name: Install Dependencies [Prover]
|
||||
run: brew install nasm m4
|
||||
@ -1007,11 +1017,11 @@ jobs:
|
||||
os: ${{ env.OS }}
|
||||
arch: ${{ env.ARCH }}
|
||||
|
||||
- name: Compile ZKSign Witness Generator
|
||||
- name: Compile Signature Witness Generator
|
||||
uses: ./.github/actions/compile-witness-generator
|
||||
with:
|
||||
circuit-name-display: "ZKSign"
|
||||
circuit-name-binary: "zksign"
|
||||
circuit-name-display: "Signature"
|
||||
circuit-name-binary: "signature"
|
||||
circuit-path: "mantle/signature.circom"
|
||||
version: ${{ env.VERSION }}
|
||||
os: ${{ env.OS }}
|
||||
@ -1039,11 +1049,11 @@ jobs:
|
||||
name: poq-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/poq-artifact
|
||||
|
||||
- name: Download ZKSign Witness Generator
|
||||
- name: Download Signature Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: zksign-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/zksign-artifact
|
||||
name: signature-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
path: witness-generators/signature-artifact
|
||||
|
||||
- name: Download PoC Witness Generator
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
@ -1074,7 +1084,7 @@ jobs:
|
||||
BUNDLE_NAME: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}
|
||||
run: |
|
||||
# Create the bundle directory structure
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,zksign,poc}
|
||||
mkdir -p "${BUNDLE_NAME}"/{pol,poq,signature,poc}
|
||||
|
||||
# Create VERSION file
|
||||
echo "${{ env.VERSION }}" > "${BUNDLE_NAME}/VERSION"
|
||||
@ -1087,29 +1097,27 @@ jobs:
|
||||
chmod +x "${BUNDLE_NAME}/prover"
|
||||
chmod +x "${BUNDLE_NAME}/verifier"
|
||||
|
||||
# Move witness generators into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/pol "${BUNDLE_NAME}/pol/witness_generator"
|
||||
# Move witness libraries into their respective circuit directories
|
||||
mv witness-generators/pol-artifact/libpol.a "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/pol-artifact/pol.dat "${BUNDLE_NAME}/pol/witness_generator.dat"
|
||||
mv witness-generators/poq-artifact/poq "${BUNDLE_NAME}/poq/witness_generator"
|
||||
cp -r witness-generators/pol-artifact/include "${BUNDLE_NAME}/pol/"
|
||||
mv witness-generators/poq-artifact/libpoq.a "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/poq-artifact/poq.dat "${BUNDLE_NAME}/poq/witness_generator.dat"
|
||||
mv witness-generators/zksign-artifact/signature "${BUNDLE_NAME}/zksign/witness_generator"
|
||||
mv witness-generators/zksign-artifact/signature.dat "${BUNDLE_NAME}/zksign/witness_generator.dat"
|
||||
mv witness-generators/poc-artifact/poc "${BUNDLE_NAME}/poc/witness_generator"
|
||||
cp -r witness-generators/poq-artifact/include "${BUNDLE_NAME}/poq/"
|
||||
mv witness-generators/signature-artifact/libsignature.a "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/signature-artifact/signature.dat "${BUNDLE_NAME}/signature/witness_generator.dat"
|
||||
cp -r witness-generators/signature-artifact/include "${BUNDLE_NAME}/signature/"
|
||||
mv witness-generators/poc-artifact/libpoc.a "${BUNDLE_NAME}/poc/"
|
||||
mv witness-generators/poc-artifact/poc.dat "${BUNDLE_NAME}/poc/witness_generator.dat"
|
||||
|
||||
# Restore execute permissions on witness generators
|
||||
chmod +x "${BUNDLE_NAME}/pol/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/poq/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/zksign/witness_generator"
|
||||
chmod +x "${BUNDLE_NAME}/poc/witness_generator"
|
||||
cp -r witness-generators/poc-artifact/include "${BUNDLE_NAME}/poc/"
|
||||
|
||||
# Copy proving keys and verification keys into each circuit directory
|
||||
cp proving-keys/pol-proving-key/pol.zkey "${BUNDLE_NAME}/pol/proving_key.zkey"
|
||||
cp proving-keys/pol-proving-key/pol_verification_key.json "${BUNDLE_NAME}/pol/verification_key.json"
|
||||
cp proving-keys/poq-proving-key/poq.zkey "${BUNDLE_NAME}/poq/proving_key.zkey"
|
||||
cp proving-keys/poq-proving-key/poq_verification_key.json "${BUNDLE_NAME}/poq/verification_key.json"
|
||||
cp proving-keys/zksign-proving-key/zksign.zkey "${BUNDLE_NAME}/zksign/proving_key.zkey"
|
||||
cp proving-keys/zksign-proving-key/zksign_verification_key.json "${BUNDLE_NAME}/zksign/verification_key.json"
|
||||
cp proving-keys/signature-proving-key/signature.zkey "${BUNDLE_NAME}/signature/proving_key.zkey"
|
||||
cp proving-keys/signature-proving-key/signature_verification_key.json "${BUNDLE_NAME}/signature/verification_key.json"
|
||||
cp proving-keys/poc-proving-key/poc.zkey "${BUNDLE_NAME}/poc/proving_key.zkey"
|
||||
cp proving-keys/poc-proving-key/poc_verification_key.json "${BUNDLE_NAME}/poc/verification_key.json"
|
||||
|
||||
@ -1122,6 +1130,119 @@ jobs:
|
||||
name: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
|
||||
# The following `Clippy` and `Test` jobs require the library circuits to compile the target repositories.
|
||||
# To avoid specifying the circuit build job multiple times across the CI, the `Clippy` and `Test` jobs are
|
||||
# defined in the same workflow as the `Build` job.
|
||||
# Ideally, if and when the build system is moved to an agnostic tool (such as `cmake`) and that is integrated into
|
||||
# the sys crates' `build.rs`, these jobs will be moved to their own workflows.
|
||||
clippy:
|
||||
name: Clippy
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
- build-linux
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
OS: linux
|
||||
ARCH: x86_64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt install -y libgmp-dev
|
||||
|
||||
- name: Cache Cargo artifacts
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # Version 4.2.3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
rust/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
- name: Download Linux Bundle
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: circuit-libs/
|
||||
|
||||
- name: Extract Bundle
|
||||
run: tar -xzf circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz -C circuit-libs/
|
||||
|
||||
- name: Clippy
|
||||
run: >
|
||||
cargo clippy
|
||||
--manifest-path rust/Cargo.toml
|
||||
--all
|
||||
--all-targets
|
||||
--all-features
|
||||
--
|
||||
-D warnings
|
||||
env:
|
||||
LBC_POC_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/poc
|
||||
LBC_POL_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/pol
|
||||
LBC_POQ_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/poq
|
||||
LBC_SIGNATURE_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/signature
|
||||
|
||||
# See clippy above — same reason.
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- setup
|
||||
- build-linux
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
OS: linux
|
||||
ARCH: x86_64
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709
|
||||
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
- name: Install Dependencies
|
||||
run: sudo apt install -y libgmp-dev
|
||||
|
||||
- name: Cache Cargo artifacts
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # Version 4.2.3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
rust/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
- name: Download Linux Bundle
|
||||
uses: actions/download-artifact@448e3f862ab3ef47aa50ff917776823c9946035b
|
||||
with:
|
||||
name: logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz
|
||||
path: circuit-libs/
|
||||
|
||||
- name: Extract Bundle
|
||||
run: tar -xzf circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}.tar.gz -C circuit-libs/
|
||||
|
||||
- name: Test
|
||||
run: >
|
||||
cargo test
|
||||
--manifest-path rust/Cargo.toml
|
||||
--all
|
||||
--all-features
|
||||
env:
|
||||
LBC_POC_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/poc
|
||||
LBC_POL_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/pol
|
||||
LBC_POQ_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/poq
|
||||
LBC_SIGNATURE_LIB_DIR: ${{ github.workspace }}/circuit-libs/logos-blockchain-circuits-${{ env.VERSION }}-${{ env.OS }}-${{ env.ARCH }}/signature
|
||||
|
||||
publish-release:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
@ -1134,6 +1255,8 @@ jobs:
|
||||
- build-linux-aarch64
|
||||
- build-windows
|
||||
- build-macos
|
||||
- clippy
|
||||
- test
|
||||
env:
|
||||
TAG: ${{ needs.setup.outputs.tag }}
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
105
.github/workflows/lint.yml
vendored
Normal file
105
.github/workflows/lint.yml
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@85e6279cec87321a52edac9c87bce653a07cf6c2 # v4.2.2
|
||||
|
||||
# Stable toolchain for building and clippy, version and components from rust-toolchain.toml.
|
||||
- name: Install Rust Toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
|
||||
# Nightly toolchain for rustfmt only — nightly is required for formatting features not yet stable.
|
||||
- name: Install Nightly Toolchain (fmt)
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
with:
|
||||
toolchain: nightly-2026-02-28
|
||||
components: rustfmt
|
||||
override: 'false'
|
||||
|
||||
- name: Cache Cargo artifacts
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
rust/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('rust/Cargo.lock', 'rust/Cargo.toml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-cargo-
|
||||
|
||||
- name: Install taplo
|
||||
run: cargo install taplo-cli --version 0.9.3 --locked # v0.9.3
|
||||
|
||||
- name: Install cargo-deny
|
||||
run: cargo install cargo-deny --version 0.19.4 --locked # v0.19.4
|
||||
|
||||
- name: Install cargo-machete
|
||||
run: cargo install cargo-machete --version 0.9.2 --locked # v0.9.2
|
||||
|
||||
- name: Check Rust formatting
|
||||
id: fmt
|
||||
continue-on-error: true
|
||||
run: cargo +nightly-2026-02-28 fmt --manifest-path rust/Cargo.toml --all -- --check
|
||||
|
||||
- name: Audit dependencies
|
||||
id: deny
|
||||
continue-on-error: true
|
||||
run: >
|
||||
cargo deny
|
||||
--manifest-path rust/Cargo.toml
|
||||
--locked
|
||||
--all-features
|
||||
check
|
||||
--hide-inclusion-graph
|
||||
-c .cargo-deny.toml
|
||||
--show-stats
|
||||
-D warnings
|
||||
|
||||
- name: Check TOML formatting
|
||||
id: taplo-fmt
|
||||
continue-on-error: true
|
||||
run: taplo fmt --check
|
||||
|
||||
- name: Lint TOML
|
||||
id: taplo-lint
|
||||
continue-on-error: true
|
||||
run: taplo lint
|
||||
|
||||
- name: Check unused dependencies
|
||||
id: machete
|
||||
continue-on-error: true
|
||||
run: cargo machete rust/
|
||||
|
||||
- name: Report
|
||||
if: always()
|
||||
run: |
|
||||
pass="✅" fail="❌"
|
||||
failed=false
|
||||
|
||||
check() {
|
||||
local name="$1" outcome="$2"
|
||||
if [ "$outcome" = "success" ]; then
|
||||
echo "$pass $name"
|
||||
else
|
||||
echo "$fail $name ($outcome)"
|
||||
failed=true
|
||||
fi
|
||||
}
|
||||
|
||||
check "rustfmt" "${{ steps.fmt.outcome }}"
|
||||
check "cargo-deny" "${{ steps.deny.outcome }}"
|
||||
check "taplo fmt" "${{ steps.taplo-fmt.outcome }}"
|
||||
check "taplo lint" "${{ steps.taplo-lint.outcome }}"
|
||||
check "cargo-machete" "${{ steps.machete.outcome }}"
|
||||
|
||||
$failed && exit 1 || true
|
||||
16
.gitignore
vendored
16
.gitignore
vendored
@ -1,2 +1,18 @@
|
||||
.idea/
|
||||
result
|
||||
*ignore*
|
||||
|
||||
# Generated files
|
||||
*_cpp/
|
||||
*.r1cs
|
||||
**/input.json
|
||||
**/*-input.json
|
||||
|
||||
# Rust Codebase
|
||||
rust/**/target/
|
||||
|
||||
# Build
|
||||
.cache
|
||||
build
|
||||
cmake
|
||||
|
||||
|
||||
46
.pre-commit-config.yaml
Normal file
46
.pre-commit-config.yaml
Normal file
@ -0,0 +1,46 @@
|
||||
repos:
|
||||
- repo: https://github.com/doublify/pre-commit-rust
|
||||
rev: eeee35a89e69d5772bdee97db1a6a898467b686e # 1.0
|
||||
hooks:
|
||||
- id: fmt
|
||||
entry: cargo +nightly-2026-02-28 fmt --manifest-path rust/Cargo.toml --all
|
||||
pass_filenames: false
|
||||
- id: clippy
|
||||
name: cargo clippy
|
||||
entry: cargo clippy --manifest-path rust/Cargo.toml
|
||||
args:
|
||||
["--all", "--all-targets", "--all-features", "--", "-D", "warnings"]
|
||||
pass_filenames: false
|
||||
- repo: https://github.com/EmbarkStudios/cargo-deny
|
||||
rev: cfe589ec21d70996a3e44d76a8e2b9369f7e0a2f # v0.19.4
|
||||
hooks:
|
||||
- id: cargo-deny
|
||||
args:
|
||||
- --manifest-path
|
||||
- rust/Cargo.toml
|
||||
- --locked
|
||||
- --all-features
|
||||
- check
|
||||
- --hide-inclusion-graph
|
||||
- -c
|
||||
- .cargo-deny.toml
|
||||
- --show-stats
|
||||
- -D
|
||||
- warnings
|
||||
- repo: https://github.com/ComPWA/taplo-pre-commit
|
||||
rev: ade0f95ddcf661c697d4670d2cfcbe95d0048a0a # v0.9.3 # Can't update until: https://github.com/tamasfe/taplo/issues/805
|
||||
hooks:
|
||||
- id: taplo-format
|
||||
- id: taplo-lint
|
||||
- repo: https://github.com/bnjbvr/cargo-machete
|
||||
rev: ac30a525c0a8d163a92d727b3ff079ee3f6ecb08 # v0.9.2
|
||||
hooks:
|
||||
- id: cargo-machete
|
||||
args: ["rust/"]
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: cargo-hack-check
|
||||
language: script
|
||||
name: cargo hack check
|
||||
entry: ./hooks/cargo-hack.sh
|
||||
stages: [manual]
|
||||
@ -1,5 +1,42 @@
|
||||
# Contributor's Guide
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Rust](https://rustup.rs/) — the pinned toolchain version is in `rust-toolchain.toml` and will be installed automatically by `rustup`.
|
||||
- [pre-commit](https://pre-commit.com/) — used to run formatting, linting, and audit checks before each commit.
|
||||
|
||||
### Installing the Pre-Commit Hooks
|
||||
|
||||
```bash
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
This only needs to be done once after cloning the repo. Hooks will then run automatically on `git commit`.
|
||||
|
||||
### Running Checks Manually
|
||||
|
||||
To run all hooks manually against all files:
|
||||
|
||||
```bash
|
||||
pre-commit run --all-files
|
||||
```
|
||||
|
||||
### Maintenance
|
||||
|
||||
#### Rust Toolchain
|
||||
|
||||
When bumping the stable toolchain, update `channel` in `rust-toolchain.toml`. The comment there lists every other place that must be updated in sync (nightly version, CI workflows, pre-commit hooks).
|
||||
|
||||
#### Tool Versions
|
||||
|
||||
`taplo`, `cargo-deny`, and `cargo-machete` are pinned in two places that must stay in sync:
|
||||
- `.pre-commit-config.yaml` (hook `rev`)
|
||||
- `.github/workflows/lint.yml` (`cargo install --version`)
|
||||
|
||||
---
|
||||
|
||||
## Triggering a New Release for Logos Blockchain Circuits
|
||||
|
||||
To trigger a release build:
|
||||
@ -8,7 +45,8 @@ To trigger a release build:
|
||||
2. This will automatically trigger the `.github/workflows/build_circuits.yml` workflow.
|
||||
3. Once the workflow finishes, the generated artifacts will be attached to a new release.
|
||||
|
||||
> Currently, releases published this way are marked as **Draft** and **Pre-Release** to ensure that the changelog and pre-release steps are manually reviewed first.
|
||||
> Currently, releases published this way are marked as **Draft** and **Pre-Release** to ensure that the changelog and
|
||||
> pre-release steps are manually reviewed first.
|
||||
|
||||
### Generated Artifacts
|
||||
|
||||
@ -30,34 +68,41 @@ logos-blockchain-circuits-{version}-{os}-{arch}/
|
||||
├── prover[.exe]
|
||||
├── verifier[.exe]
|
||||
├── pol/
|
||||
│ ├── witness_generator[.exe]
|
||||
│ ├── libpol.a
|
||||
│ ├── witness_generator.dat
|
||||
│ ├── include/
|
||||
│ ├── proving_key.zkey
|
||||
│ └── verification_key.json
|
||||
├── poq/
|
||||
│ ├── witness_generator[.exe]
|
||||
│ ├── libpoq.a
|
||||
│ ├── witness_generator.dat
|
||||
│ ├── include/
|
||||
│ ├── proving_key.zkey
|
||||
│ └── verification_key.json
|
||||
├── zksign/
|
||||
│ ├── witness_generator[.exe]
|
||||
├── signature/
|
||||
│ ├── libsignature.a
|
||||
│ ├── witness_generator.dat
|
||||
│ ├── include/
|
||||
│ ├── proving_key.zkey
|
||||
│ └── verification_key.json
|
||||
└── poc/
|
||||
├── witness_generator[.exe]
|
||||
├── libpoc.a
|
||||
├── witness_generator.dat
|
||||
├── include/
|
||||
├── proving_key.zkey
|
||||
└── verification_key.json
|
||||
```
|
||||
|
||||
> On Windows, static libraries use the `.lib` extension instead of `.a` (e.g. `pol.lib`).
|
||||
|
||||
At the root level:
|
||||
- **prover**: Rapidsnark prover binary for generating zk-SNARK proofs
|
||||
- **verifier**: Rapidsnark verifier binary for verifying proofs
|
||||
|
||||
Each circuit directory contains:
|
||||
- **witness_generator**: Compiled C++ binary for generating witnesses from inputs
|
||||
- **lib{circuit}.a / {circuit}.lib**: Static library for generating witnesses from inputs
|
||||
- **witness_generator.dat**: Required data file for the witness generator
|
||||
- **include/**: C headers for linking against the witness generator library
|
||||
- **proving_key.zkey**: Groth16 proving key for generating zk-SNARK proofs
|
||||
- **verification_key.json**: Verification key for verifying proofs
|
||||
|
||||
|
||||
64
blend/test_ffi.cpp
Normal file
64
blend/test_ffi.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "poq/ffi.hpp"
|
||||
|
||||
static uint8_t* read_file(const char* path, size_t* out_size) {
|
||||
FILE* f = fopen(path, "rb");
|
||||
if (!f) return nullptr;
|
||||
fseek(f, 0, SEEK_END);
|
||||
*out_size = ftell(f);
|
||||
rewind(f);
|
||||
uint8_t* buf = (uint8_t*)malloc(*out_size + 1);
|
||||
fread(buf, 1, *out_size, f);
|
||||
buf[*out_size] = '\0';
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Status status = poq_generate_witness_from_files(
|
||||
"poq",
|
||||
"../poq-input.json",
|
||||
"witness.wtns"
|
||||
);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("generate_witness_from_files: OK\n");
|
||||
|
||||
size_t dat_size, json_size;
|
||||
uint8_t* dat_data = read_file("poq.dat", &dat_size);
|
||||
uint8_t* json_data = read_file("../poq-input.json", &json_size);
|
||||
|
||||
WitnessInput input = {
|
||||
{dat_data, dat_size},
|
||||
(const char*)json_data
|
||||
};
|
||||
Bytes output = {nullptr, 0};
|
||||
|
||||
status = poq_generate_witness(&input, &output);
|
||||
|
||||
free(dat_data);
|
||||
free(json_data);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t wtns_size;
|
||||
uint8_t* wtns_data = read_file("witness.wtns", &wtns_size);
|
||||
assert(wtns_data != nullptr);
|
||||
assert(output.size == wtns_size);
|
||||
assert(memcmp(output.data, wtns_data, output.size) == 0);
|
||||
free(wtns_data);
|
||||
|
||||
printf("generate_witness: OK (%zu bytes, matches witness.wtns)\n", output.size);
|
||||
free_bytes(&output);
|
||||
return 0;
|
||||
}
|
||||
8
flake.lock
generated
8
flake.lock
generated
@ -2,16 +2,16 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1769461804,
|
||||
"narHash": "sha256-msG8SU5WsBUfVVa/9RPLaymvi5bI8edTavbIq3vRlhI=",
|
||||
"lastModified": 1767313136,
|
||||
"narHash": "sha256-16KkgfdYqjaeRGBaYsNrhPRRENs0qzkQVUooNHtoy2w=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bfc1b8a4574108ceef22f02bafcf6611380c100d",
|
||||
"rev": "ac62194c3917d5f474c1a844b6fd6da2db95077d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"ref": "nixos-25.05",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
description = "Logos Blockchain Circuits (GitHub Releases)";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
|
||||
};
|
||||
|
||||
outputs =
|
||||
@ -19,7 +19,8 @@
|
||||
|
||||
forAll = lib.genAttrs systems;
|
||||
|
||||
circuitsVersion = "0.4.1"; # TODO: Parametrize or make package per version available
|
||||
cargoToml = builtins.fromTOML (builtins.readFile ./rust/Cargo.toml);
|
||||
circuitsVersion = cargoToml.workspace.package.version;
|
||||
versions = import ./versions.nix;
|
||||
circuitsHashes = versions.${circuitsVersion};
|
||||
|
||||
|
||||
3
hooks/cargo-hack.sh
Executable file
3
hooks/cargo-hack.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
RUSTFLAGS="-D warnings" cargo hack --feature-powerset --no-dev-deps --keep-going --all-targets check
|
||||
85
justfile
85
justfile
@ -1,3 +1,21 @@
|
||||
cargo_root := justfile_directory() + "/rust"
|
||||
src := justfile_directory() + "/src"
|
||||
ci_makefile := justfile_directory() + "/.github/resources/witness-generator/Makefile"
|
||||
circom_version := "2.2.2" # This version must match the version used in the CI
|
||||
|
||||
os := `uname -s`
|
||||
sed_i := if os == "Darwin" { "sed -i ''" } else { "sed -i" }
|
||||
|
||||
# Shortcut to run cargo commands from the repo root (the Cargo workspace lives under ./rust/).
|
||||
# Potentially temporary.
|
||||
cargo +args:
|
||||
cd {{cargo_root}} && cargo {{args}}
|
||||
|
||||
# Verify the installed circom matches the pinned version.
|
||||
check-circom:
|
||||
@circom --version | grep -qF "{{circom_version}}" || \
|
||||
(echo "circom {{circom_version}} required; got: $(circom --version 2>&1)" >&2; exit 1)
|
||||
|
||||
prettify:
|
||||
nix shell nixpkgs#clang-tools -c clang-format -i src/**.cpp src/**.hpp
|
||||
|
||||
@ -10,3 +28,70 @@ sage-run script +args='':
|
||||
-v "{{justfile_directory()}}:/work" \
|
||||
-w "/work/$(dirname '{{script}}')" \
|
||||
sagemath/sagemath sage "$(basename '{{script}}')" {{args}}
|
||||
|
||||
# Build the PoQ circuit and its C++ witness generator, equivalent to the CI build.
|
||||
poq: check-circom
|
||||
circom blend/poq.circom --c --r1cs --no_asm --O2 --output blend
|
||||
# circom-generated main() has no return on the success path; patch it before -O3 turns it into an infinite loop
|
||||
{{sed_i}} ':a;N;$!ba;s/\n}\n\n*$/\n return 0;\n}/' blend/poq_cpp/main.cpp
|
||||
cp -r {{src}}/poq blend/poq_cpp/poq
|
||||
cp {{src}}/circom_adapter.cpp {{src}}/circom_adapter.hpp {{src}}/circom_fwd.hpp {{src}}/types.hpp blend/poq_cpp/
|
||||
cp {{ci_makefile}} blend/poq_cpp/Makefile
|
||||
cp blend/test_ffi.cpp blend/poq_cpp/test_ffi.cpp
|
||||
make -C blend/poq_cpp PROJECT=poq linux-lib
|
||||
|
||||
# Run a simple smoke test of the PoQ witness generator.
|
||||
test-poq: poq
|
||||
g++ -std=c++11 -O3 -I blend/poq_cpp blend/poq_cpp/test_ffi.cpp -L blend/poq_cpp -lwitness_poq -lgmp -o blend/poq_cpp/test_ffi
|
||||
cd blend/poq_cpp && ./test_ffi
|
||||
|
||||
# Build the PoL circuit and its C++ witness generator, equivalent to the CI build.
|
||||
pol: check-circom
|
||||
circom mantle/pol.circom --c --r1cs --no_asm --O2 --output mantle
|
||||
# circom-generated main() has no return on the success path; patch it before -O3 turns it into an infinite loop
|
||||
{{sed_i}} ':a;N;$!ba;s/\n}\n\n*$/\n return 0;\n}/' mantle/pol_cpp/main.cpp
|
||||
cp -r {{src}}/pol mantle/pol_cpp/pol
|
||||
cp {{src}}/circom_adapter.cpp {{src}}/circom_adapter.hpp {{src}}/circom_fwd.hpp {{src}}/types.hpp mantle/pol_cpp/
|
||||
cp {{ci_makefile}} mantle/pol_cpp/Makefile
|
||||
cp mantle/test_pol.cpp mantle/pol_cpp/test_pol.cpp
|
||||
make -C mantle/pol_cpp PROJECT=pol linux-lib
|
||||
|
||||
# Run a simple smoke test of the PoL witness generator.
|
||||
test-pol: pol
|
||||
g++ -std=c++11 -O3 -I mantle/pol_cpp mantle/pol_cpp/test_pol.cpp -L mantle/pol_cpp -lwitness_pol -lgmp -o mantle/pol_cpp/test_pol
|
||||
cd mantle/pol_cpp && ./test_pol
|
||||
|
||||
# Build the PoC circuit and its C++ witness generator, equivalent to the CI build.
|
||||
poc: check-circom
|
||||
circom mantle/poc.circom --c --r1cs --no_asm --O2 --output mantle
|
||||
# circom-generated main() has no return on the success path; patch it before -O3 turns it into an infinite loop
|
||||
{{sed_i}} ':a;N;$!ba;s/\n}\n\n*$/\n return 0;\n}/' mantle/poc_cpp/main.cpp
|
||||
cp -r {{src}}/poc mantle/poc_cpp/poc
|
||||
cp {{src}}/circom_adapter.cpp {{src}}/circom_adapter.hpp {{src}}/circom_fwd.hpp {{src}}/types.hpp mantle/poc_cpp/
|
||||
cp {{ci_makefile}} mantle/poc_cpp/Makefile
|
||||
cp mantle/test_poc.cpp mantle/poc_cpp/test_poc.cpp
|
||||
make -C mantle/poc_cpp PROJECT=poc linux-lib
|
||||
|
||||
# Run a simple smoke test of the PoC witness generator.
|
||||
test-poc: poc
|
||||
g++ -std=c++11 -O3 -I mantle/poc_cpp mantle/poc_cpp/test_poc.cpp -L mantle/poc_cpp -lwitness_poc -lgmp -o mantle/poc_cpp/test_poc
|
||||
cd mantle/poc_cpp && ./test_poc
|
||||
|
||||
# Build the signature circuit and its C++ witness generator, equivalent to the CI build.
|
||||
signature: check-circom
|
||||
circom mantle/signature.circom --c --r1cs --no_asm --O2 --output mantle
|
||||
# circom-generated main() has no return on the success path; patch it before -O3 turns it into an infinite loop
|
||||
{{sed_i}} ':a;N;$!ba;s/\n}\n\n*$/\n return 0;\n}/' mantle/signature_cpp/main.cpp
|
||||
cp -r {{src}}/signature mantle/signature_cpp/signature
|
||||
cp {{src}}/circom_adapter.cpp {{src}}/circom_adapter.hpp {{src}}/circom_fwd.hpp {{src}}/types.hpp mantle/signature_cpp/
|
||||
cp {{ci_makefile}} mantle/signature_cpp/Makefile
|
||||
cp mantle/test_signature.cpp mantle/signature_cpp/test_signature.cpp
|
||||
make -C mantle/signature_cpp PROJECT=signature linux-lib
|
||||
|
||||
# Run a simple smoke test of the signature witness generator.
|
||||
test-signature: signature
|
||||
g++ -std=c++11 -O3 -I mantle/signature_cpp mantle/signature_cpp/test_signature.cpp -L mantle/signature_cpp -lwitness_signature -lgmp -o mantle/signature_cpp/test_signature
|
||||
cd mantle/signature_cpp && ./test_signature
|
||||
|
||||
clean:
|
||||
rm -rf blend/poq_cpp mantle/pol_cpp mantle/poc_cpp mantle/signature_cpp
|
||||
|
||||
64
mantle/test_poc.cpp
Normal file
64
mantle/test_poc.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "poc/ffi.hpp"
|
||||
|
||||
static uint8_t* read_file(const char* path, size_t* out_size) {
|
||||
FILE* f = fopen(path, "rb");
|
||||
if (!f) return nullptr;
|
||||
fseek(f, 0, SEEK_END);
|
||||
*out_size = ftell(f);
|
||||
rewind(f);
|
||||
uint8_t* buf = (uint8_t*)malloc(*out_size + 1);
|
||||
fread(buf, 1, *out_size, f);
|
||||
buf[*out_size] = '\0';
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Status status = poc_generate_witness_from_files(
|
||||
"poc",
|
||||
"../poc-input.json",
|
||||
"witness.wtns"
|
||||
);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("generate_witness_from_files: OK\n");
|
||||
|
||||
size_t dat_size, json_size;
|
||||
uint8_t* dat_data = read_file("poc.dat", &dat_size);
|
||||
uint8_t* json_data = read_file("../poc-input.json", &json_size);
|
||||
|
||||
WitnessInput input = {
|
||||
{dat_data, dat_size},
|
||||
(const char*)json_data
|
||||
};
|
||||
Bytes output = {nullptr, 0};
|
||||
|
||||
status = poc_generate_witness(&input, &output);
|
||||
|
||||
free(dat_data);
|
||||
free(json_data);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t wtns_size;
|
||||
uint8_t* wtns_data = read_file("witness.wtns", &wtns_size);
|
||||
assert(wtns_data != nullptr);
|
||||
assert(output.size == wtns_size);
|
||||
assert(memcmp(output.data, wtns_data, output.size) == 0);
|
||||
free(wtns_data);
|
||||
|
||||
printf("generate_witness: OK (%zu bytes, matches witness.wtns)\n", output.size);
|
||||
free_bytes(&output);
|
||||
return 0;
|
||||
}
|
||||
64
mantle/test_pol.cpp
Normal file
64
mantle/test_pol.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "pol/ffi.hpp"
|
||||
|
||||
static uint8_t* read_file(const char* path, size_t* out_size) {
|
||||
FILE* f = fopen(path, "rb");
|
||||
if (!f) return nullptr;
|
||||
fseek(f, 0, SEEK_END);
|
||||
*out_size = ftell(f);
|
||||
rewind(f);
|
||||
uint8_t* buf = (uint8_t*)malloc(*out_size + 1);
|
||||
fread(buf, 1, *out_size, f);
|
||||
buf[*out_size] = '\0';
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Status status = pol_generate_witness_from_files(
|
||||
"pol",
|
||||
"../pol-input.json",
|
||||
"witness.wtns"
|
||||
);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("generate_witness_from_files: OK\n");
|
||||
|
||||
size_t dat_size, json_size;
|
||||
uint8_t* dat_data = read_file("pol.dat", &dat_size);
|
||||
uint8_t* json_data = read_file("../pol-input.json", &json_size);
|
||||
|
||||
WitnessInput input = {
|
||||
{dat_data, dat_size},
|
||||
(const char*)json_data
|
||||
};
|
||||
Bytes output = {nullptr, 0};
|
||||
|
||||
status = pol_generate_witness(&input, &output);
|
||||
|
||||
free(dat_data);
|
||||
free(json_data);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t wtns_size;
|
||||
uint8_t* wtns_data = read_file("witness.wtns", &wtns_size);
|
||||
assert(wtns_data != nullptr);
|
||||
assert(output.size == wtns_size);
|
||||
assert(memcmp(output.data, wtns_data, output.size) == 0);
|
||||
free(wtns_data);
|
||||
|
||||
printf("generate_witness: OK (%zu bytes, matches witness.wtns)\n", output.size);
|
||||
free_bytes(&output);
|
||||
return 0;
|
||||
}
|
||||
64
mantle/test_signature.cpp
Normal file
64
mantle/test_signature.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "signature/ffi.hpp"
|
||||
|
||||
static uint8_t* read_file(const char* path, size_t* out_size) {
|
||||
FILE* f = fopen(path, "rb");
|
||||
if (!f) return nullptr;
|
||||
fseek(f, 0, SEEK_END);
|
||||
*out_size = ftell(f);
|
||||
rewind(f);
|
||||
uint8_t* buf = (uint8_t*)malloc(*out_size + 1);
|
||||
fread(buf, 1, *out_size, f);
|
||||
buf[*out_size] = '\0';
|
||||
fclose(f);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Status status = signature_generate_witness_from_files(
|
||||
"signature",
|
||||
"../signature-input.json",
|
||||
"witness.wtns"
|
||||
);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("generate_witness_from_files: OK\n");
|
||||
|
||||
size_t dat_size, json_size;
|
||||
uint8_t* dat_data = read_file("signature.dat", &dat_size);
|
||||
uint8_t* json_data = read_file("../signature-input.json", &json_size);
|
||||
|
||||
WitnessInput input = {
|
||||
{dat_data, dat_size},
|
||||
(const char*)json_data
|
||||
};
|
||||
Bytes output = {nullptr, 0};
|
||||
|
||||
status = signature_generate_witness(&input, &output);
|
||||
|
||||
free(dat_data);
|
||||
free(json_data);
|
||||
|
||||
if (status_is_error(status)) {
|
||||
fprintf(stderr, "Error [%d]: %s\n", status.code, status.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t wtns_size;
|
||||
uint8_t* wtns_data = read_file("witness.wtns", &wtns_size);
|
||||
assert(wtns_data != nullptr);
|
||||
assert(output.size == wtns_size);
|
||||
assert(memcmp(output.data, wtns_data, output.size) == 0);
|
||||
free(wtns_data);
|
||||
|
||||
printf("generate_witness: OK (%zu bytes, matches witness.wtns)\n", output.size);
|
||||
free_bytes(&output);
|
||||
return 0;
|
||||
}
|
||||
7
rust-toolchain.toml
Normal file
7
rust-toolchain.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[toolchain]
|
||||
# Also, update the version of the nightly toolchain to the latest nightly of the new version specified in the following places:
|
||||
# * .github/workflows/lint.yml (fmt step)
|
||||
# * .pre-commit-config.yaml (fmt hook)
|
||||
channel = "1.95.0"
|
||||
# Even if clippy should be included in the default profile, in some cases it is not installed. So we force it with an explicit declaration.
|
||||
components = ["clippy"]
|
||||
606
rust/Cargo.lock
generated
Normal file
606
rust/Cargo.lock
generated
Normal file
@ -0,0 +1,606 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fd-lock"
|
||||
version = "4.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.186"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
"plain",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-build"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"fd-lock",
|
||||
"flate2",
|
||||
"tar",
|
||||
"ureq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-common"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-poc-sys"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
"logos-blockchain-circuits-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-pol-sys"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
"logos-blockchain-circuits-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-poq-sys"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
"logos-blockchain-circuits-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-signature-sys"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-common",
|
||||
"logos-blockchain-circuits-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-types"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
|
||||
|
||||
[[package]]
|
||||
name = "plain"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"libredox",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.23.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pki-types"
|
||||
version = "1.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9"
|
||||
dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.103.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "ureq"
|
||||
version = "3.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dea7109cdcd5864d4eeb1b58a1648dc9bf520360d7af16ec26d0a9354bafcfc0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"flate2",
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"ureq-proto",
|
||||
"utf8-zero",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ureq-proto"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e994ba84b0bd1b1b0cf92878b7ef898a5c1760108fe7b6010327e274917a808c"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"http",
|
||||
"httparse",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utf8-zero"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8c0a043c9540bae7c578c88f91dda8bd82e59ae27c21baca69c8b191aaf5a6e"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||
192
rust/Cargo.toml
Normal file
192
rust/Cargo.toml
Normal file
@ -0,0 +1,192 @@
|
||||
[workspace.package]
|
||||
categories = ["cryptography", "external-ffi-bindings"]
|
||||
description = "Rust bindings for the Logos Blockchain Circuits, providing a safe and efficient interface for interacting with the underlying cryptographic circuits."
|
||||
edition = "2024"
|
||||
keywords = ["blockchain", "privacy"]
|
||||
license = "MIT or Apache-2.0"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/logos-blockchain/logos-blockchain-circuits"
|
||||
version = "0.5.0"
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"logos-blockchain-circuits-build",
|
||||
"logos-blockchain-circuits-poc-sys",
|
||||
"logos-blockchain-circuits-pol-sys",
|
||||
"logos-blockchain-circuits-poq-sys",
|
||||
"logos-blockchain-circuits-signature-sys",
|
||||
"logos-blockchain-circuits-types",
|
||||
"logos-blockchain-circuits-common",
|
||||
]
|
||||
resolver = "3"
|
||||
|
||||
[workspace.dependencies]
|
||||
# Internal
|
||||
lbc-common = { default-features = false, package = "logos-blockchain-circuits-common", path = "./logos-blockchain-circuits-common" }
|
||||
lbc-build = { package = "logos-blockchain-circuits-build", path = "./logos-blockchain-circuits-build" }
|
||||
lbc-poc-sys = { default-features = false, package = "logos-blockchain-circuits-poc-sys", path = "./logos-blockchain-circuits-poc-sys" }
|
||||
lbc-pol-sys = { default-features = false, package = "logos-blockchain-circuits-pol-sys", path = "./logos-blockchain-circuits-pol-sys" }
|
||||
lbc-poq-sys = { default-features = false, package = "logos-blockchain-circuits-poq-sys", path = "./logos-blockchain-circuits-poq-sys" }
|
||||
lbc-signature-sys = { default-features = false, package = "logos-blockchain-circuits-signature-sys", path = "./logos-blockchain-circuits-signature-sys" }
|
||||
lbc-types = { default-features = false, package = "logos-blockchain-circuits-types", path = "./logos-blockchain-circuits-types" }
|
||||
|
||||
# External
|
||||
dirs = "^6"
|
||||
fd-lock = "^4"
|
||||
flate2 = "^1.1"
|
||||
libc = "^0.2"
|
||||
tar = "^0.4"
|
||||
ureq = "^3.3"
|
||||
bytes = "^1.11"
|
||||
|
||||
# Sourced from https://github.com/logos-co/nomos/blob/main/Cargo.toml
|
||||
[workspace.lints.clippy]
|
||||
|
||||
# Cargo and allowed cargo warnings (new lints will warn by default)
|
||||
cargo = { level = "warn", priority = -1 }
|
||||
|
||||
# TODO: We should tackle this lint at some point, to reduce dependencies duplication, reduce compilation times and bring down our binary size.
|
||||
multiple_crate_versions = { level = "allow" }
|
||||
|
||||
# Nursery and allowed nursery warnings (new lints will warn by default)
|
||||
nursery = { level = "warn", priority = -1 }
|
||||
|
||||
# Pedantic and allowed pedantic warnings (new lints will warn by default)
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
|
||||
similar_names = { level = "allow" }
|
||||
|
||||
# Restriction and allowed restriction warnings (new lints will warn by default)
|
||||
restriction = { level = "warn", priority = -1 }
|
||||
|
||||
absolute_paths = { level = "allow" }
|
||||
alloc_instead_of_core = { level = "allow" }
|
||||
arbitrary_source_item_ordering = { level = "allow" }
|
||||
big_endian_bytes = { level = "allow" }
|
||||
blanket_clippy_restriction_lints = { level = "allow" }
|
||||
decimal_literal_representation = { level = "allow" }
|
||||
default_numeric_fallback = { level = "allow" }
|
||||
deref_by_slicing = { level = "allow" }
|
||||
else_if_without_else = { level = "allow" }
|
||||
exhaustive_enums = { level = "allow" }
|
||||
exhaustive_structs = { level = "allow" }
|
||||
exit = { level = "allow" }
|
||||
expect_used = { level = "allow" }
|
||||
field_scoped_visibility_modifiers = { level = "allow" }
|
||||
float_arithmetic = { level = "allow" }
|
||||
get_unwrap = { level = "allow" }
|
||||
host_endian_bytes = { level = "allow" }
|
||||
implicit_return = { level = "allow" }
|
||||
integer_division_remainder_used = { level = "allow" }
|
||||
iter_over_hash_type = { level = "allow" }
|
||||
let_underscore_must_use = { level = "allow" }
|
||||
let_underscore_untyped = { level = "allow" }
|
||||
little_endian_bytes = { level = "allow" }
|
||||
map_err_ignore = { level = "allow" }
|
||||
min_ident_chars = { level = "allow" }
|
||||
missing_asserts_for_indexing = { level = "allow" }
|
||||
missing_docs_in_private_items = { level = "allow" }
|
||||
missing_inline_in_public_items = { level = "allow" }
|
||||
missing_trait_methods = { level = "allow" }
|
||||
mixed_read_write_in_expression = { level = "allow" }
|
||||
mod_module_files = { level = "allow" }
|
||||
module_name_repetitions = { level = "allow" }
|
||||
modulo_arithmetic = { level = "allow" }
|
||||
panic = { level = "allow" }
|
||||
panic_in_result_fn = { level = "allow" }
|
||||
partial_pub_fields = { level = "allow" }
|
||||
print_stderr = { level = "allow" }
|
||||
print_stdout = { level = "allow" }
|
||||
pub_use = { level = "allow" }
|
||||
pub_with_shorthand = { level = "allow" }
|
||||
question_mark_used = { level = "allow" }
|
||||
self_named_module_files = { level = "allow" }
|
||||
semicolon_inside_block = { level = "allow" }
|
||||
single_call_fn = { level = "allow" }
|
||||
single_char_lifetime_names = { level = "allow" }
|
||||
std_instead_of_alloc = { level = "allow" }
|
||||
std_instead_of_core = { level = "allow" }
|
||||
struct_field_names = { level = "allow" }
|
||||
unseparated_literal_suffix = { level = "allow" }
|
||||
use_debug = { level = "allow" }
|
||||
wildcard_enum_match_arm = { level = "allow" }
|
||||
|
||||
# TODO: Address these lints at some point. To allow them, move them to the section where they belong (e.g., pedantic), and keep allowing them. To enforce them, since all lints are "warn" by default, just remove them from this list.
|
||||
arithmetic_side_effects = { level = "allow" }
|
||||
as_conversions = { level = "allow" }
|
||||
as_pointer_underscore = { level = "allow" }
|
||||
as_underscore = { level = "allow" }
|
||||
assertions_on_result_states = { level = "allow" }
|
||||
cast_possible_truncation = { level = "allow" }
|
||||
cast_possible_wrap = { level = "allow" }
|
||||
cast_precision_loss = { level = "allow" }
|
||||
cast_sign_loss = { level = "allow" }
|
||||
doc_paragraphs_missing_punctuation = { level = "allow" }
|
||||
error_impl_error = { level = "allow" }
|
||||
impl_trait_in_params = { level = "allow" }
|
||||
indexing_slicing = { level = "allow" }
|
||||
infinite_loop = { level = "allow" }
|
||||
integer_division = { level = "allow" }
|
||||
large_stack_frames = { level = "allow" }
|
||||
missing_assert_message = { level = "allow" }
|
||||
missing_errors_doc = { level = "allow" }
|
||||
missing_panics_doc = { level = "allow" }
|
||||
pattern_type_mismatch = { level = "allow" }
|
||||
redundant_test_prefix = { level = "allow" }
|
||||
ref_patterns = { level = "allow" }
|
||||
renamed_function_params = { level = "allow" }
|
||||
same_name_method = { level = "allow" }
|
||||
shadow_reuse = { level = "allow" }
|
||||
shadow_same = { level = "allow" }
|
||||
shadow_unrelated = { level = "allow" }
|
||||
tests_outside_test_module = { level = "allow" }
|
||||
todo = { level = "allow" }
|
||||
unchecked_time_subtraction = { level = "allow" }
|
||||
unimplemented = { level = "allow" }
|
||||
unreachable = { level = "allow" }
|
||||
unwrap_in_result = { level = "allow" }
|
||||
unwrap_used = { level = "allow" }
|
||||
|
||||
[workspace.lints.rust]
|
||||
|
||||
# Explicitly allowed lints
|
||||
|
||||
unused_crate_dependencies = { level = "allow" } # Too many false positives especially around benchmarking and binaries, which do not have their own `dependencies` section yet. Plus, we have cargo-machete checking unused deps.
|
||||
unused_results = { level = "allow" } # We have Clippy lints to warn on unused `must_use` results. This is too pedantic as it complains on EVERY unused result.
|
||||
|
||||
# Lints which are allow-by-default but have been changed to "warn"
|
||||
ambiguous_negative_literals = { level = "warn" }
|
||||
closure_returning_async_block = { level = "warn" }
|
||||
deref_into_dyn_supertrait = { level = "warn" }
|
||||
impl_trait_redundant_captures = { level = "warn" }
|
||||
let_underscore_drop = { level = "warn" }
|
||||
macro_use_extern_crate = { level = "warn" }
|
||||
missing_unsafe_on_extern = { level = "warn" }
|
||||
redundant_imports = { level = "warn" }
|
||||
redundant_lifetimes = { level = "warn" }
|
||||
single_use_lifetimes = { level = "warn" }
|
||||
tail_expr_drop_order = { level = "warn" }
|
||||
trivial_numeric_casts = { level = "warn" }
|
||||
unit_bindings = { level = "warn" }
|
||||
unsafe_attr_outside_unsafe = { level = "warn" }
|
||||
unsafe_op_in_unsafe_fn = { level = "warn" }
|
||||
unstable_features = { level = "warn" }
|
||||
unused_extern_crates = { level = "warn" }
|
||||
unused_import_braces = { level = "warn" }
|
||||
unused_lifetimes = { level = "warn" }
|
||||
unused_macro_rules = { level = "warn" }
|
||||
unused_qualifications = { level = "warn" }
|
||||
|
||||
# TODO: Address these allow-by-default Rustc lints at some point. To allow them, move them to the list of explicitly allowed lints. To enforce them, move them to the list of explicitly warned ones.
|
||||
absolute_paths_not_starting_with_crate = { level = "allow" }
|
||||
elided_lifetimes_in_paths = { level = "allow" }
|
||||
ffi_unwind_calls = { level = "allow" }
|
||||
impl_trait_overcaptures = { level = "allow" }
|
||||
linker_messages = { level = "allow" }
|
||||
missing_copy_implementations = { level = "allow" }
|
||||
missing_debug_implementations = { level = "allow" }
|
||||
missing_docs = { level = "allow" }
|
||||
trivial_casts = { level = "allow" }
|
||||
unreachable_pub = { level = "allow" }
|
||||
unsafe_code = { level = "allow" }
|
||||
variant_size_differences = { level = "allow" }
|
||||
2
rust/README.md
Normal file
2
rust/README.md
Normal file
@ -0,0 +1,2 @@
|
||||
# Logos Blockchain Circuits – Rust
|
||||
This directory contains the Rust FFI to interact with the Logos Blockchain Circuits.
|
||||
23
rust/logos-blockchain-circuits-build/Cargo.toml
Normal file
23
rust/logos-blockchain-circuits-build/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-build"
|
||||
categories.workspace = true
|
||||
description = "Shared build script logic for Logos Blockchain Circuits sys crates."
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[features]
|
||||
prebuilt = ["dep:dirs", "dep:fd-lock", "dep:flate2", "dep:tar", "dep:ureq"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
dirs = { workspace = true, optional = true }
|
||||
fd-lock = { workspace = true, optional = true }
|
||||
flate2 = { workspace = true, optional = true }
|
||||
tar = { workspace = true, optional = true }
|
||||
ureq = { workspace = true, optional = true }
|
||||
161
rust/logos-blockchain-circuits-build/src/lib.rs
Normal file
161
rust/logos-blockchain-circuits-build/src/lib.rs
Normal file
@ -0,0 +1,161 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[cfg(feature = "prebuilt")]
|
||||
mod prebuilt {
|
||||
use std::path::{Path, PathBuf};
|
||||
use ureq::Body;
|
||||
use ureq::http::Response;
|
||||
|
||||
static REPO: &str = "logos-blockchain/logos-blockchain-circuits";
|
||||
static ARTIFACT_PREFIX: &str = "logos-blockchain-circuits";
|
||||
|
||||
fn build_artifact_name(version: &str, os: &str, arch: &str) -> String {
|
||||
format!("{ARTIFACT_PREFIX}-v{version}-{os}-{arch}")
|
||||
}
|
||||
|
||||
fn build_artifact_url(version: &str, os: &str, arch: &str) -> String {
|
||||
let artifact = build_artifact_name(version, os, arch);
|
||||
let artifact_tar_gz = format!("{artifact}.tar.gz");
|
||||
format!("https://github.com/{REPO}/releases/download/v{version}/{artifact_tar_gz}")
|
||||
}
|
||||
|
||||
fn fetch_library(version: &str, os: &str, arch: &str, lib_var_name: &str) -> Response<Body> {
|
||||
let url = build_artifact_url(version, os, arch);
|
||||
// We skip checksum verification intentionally.
|
||||
// Hardcoded hashes would protect against a silently replaced release asset but require a
|
||||
// two-step release (build → hash → commit → tag) which feels overkill for a first-party
|
||||
// library.
|
||||
ureq::get(&url).call().unwrap_or_else(|error| {
|
||||
panic!(
|
||||
"Failed to download a prebuilt library for {os}-{arch} v{version}: {error}. \
|
||||
Set {lib_var_name} to point to a local build instead."
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn unpack_library(
|
||||
response: Response<Body>,
|
||||
circuit_name: &str,
|
||||
version: &str,
|
||||
os: &str,
|
||||
arch: &str,
|
||||
output_dir: &Path,
|
||||
) -> PathBuf {
|
||||
let gz_decoder = flate2::read::GzDecoder::new(response.into_body().into_reader());
|
||||
let mut archive = tar::Archive::new(gz_decoder);
|
||||
archive
|
||||
.unpack(output_dir)
|
||||
.expect("Failed to unpack the downloaded archive.");
|
||||
|
||||
let unpacked_artifact_path = output_dir.join(build_artifact_name(version, os, arch));
|
||||
let unpacked_library_directory = unpacked_artifact_path.join(circuit_name);
|
||||
|
||||
assert!(
|
||||
unpacked_library_directory.is_dir(),
|
||||
"Failed to find the unpacked library at {}",
|
||||
unpacked_library_directory.display()
|
||||
);
|
||||
|
||||
unpacked_library_directory
|
||||
}
|
||||
|
||||
/// Produce a lockfile for the given directory
|
||||
fn get_lockfile(directory: &Path) -> fd_lock::RwLock<std::fs::File> {
|
||||
let file = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.truncate(false)
|
||||
.write(true)
|
||||
.open(directory.join(".lock"))
|
||||
.expect("Failed to open cache lock file.");
|
||||
fd_lock::RwLock::new(file)
|
||||
}
|
||||
|
||||
fn get_cache_dir() -> PathBuf {
|
||||
dirs::cache_dir()
|
||||
.expect("Could not determine the cache directory for this platform.")
|
||||
.join("logos")
|
||||
.join("blockchain")
|
||||
}
|
||||
|
||||
pub fn provision_library(circuit_name: &str, lib_var_name: &str) -> PathBuf {
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
let cache = get_cache_dir();
|
||||
// The tarball unpacks to a top-level `{artifact_name}/` dir, so the circuit lives at
|
||||
// `cache/{artifact_name}/{circuit_name}/`.
|
||||
let circuit_dir = cache
|
||||
.join(build_artifact_name(version, &os, &arch))
|
||||
.join(circuit_name);
|
||||
|
||||
std::fs::create_dir_all(&cache).expect("Failed to create the cache directory.");
|
||||
|
||||
// Since the circuits' libraries are all contained in the same single artifact, each crate
|
||||
// will try to download the same circuits.
|
||||
// To avoid redundant downloads, we use a lock to ensure that only one process fetches the
|
||||
// circuits while the others wait for it to complete and then re-check the cache.
|
||||
let mut lock = get_lockfile(&cache);
|
||||
let _guard = lock.write().expect("Failed to acquire cache lock.");
|
||||
|
||||
if circuit_dir.is_dir() {
|
||||
println!(
|
||||
"Found a cached {circuit_name} library at {}, reusing.",
|
||||
circuit_dir.display()
|
||||
);
|
||||
return circuit_dir;
|
||||
}
|
||||
|
||||
println!(
|
||||
"No cached download found, downloading {circuit_name} v{version} for {os}-{arch}..."
|
||||
);
|
||||
let response = fetch_library(version, &os, &arch, lib_var_name);
|
||||
println!("Download complete, unpacking...");
|
||||
let lib_dir = unpack_library(response, circuit_name, version, &os, &arch, &cache);
|
||||
println!("Ready, {circuit_name} library at {}.", lib_dir.display());
|
||||
lib_dir
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(circuit_name: &str, lib_var_name: &str) {
|
||||
println!("cargo:rerun-if-env-changed={lib_var_name}");
|
||||
println!("cargo:rerun-if-env-changed=CARGO_PKG_VERSION");
|
||||
println!("cargo:rerun-if-changed=Cargo.toml");
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
|
||||
let lib_dir = std::env::var(lib_var_name).map_or_else(
|
||||
|_| {
|
||||
#[cfg(not(feature = "prebuilt"))]
|
||||
panic!(
|
||||
"{lib_var_name} is not set. Either:\n\
|
||||
- Set {lib_var_name} to point at a local build, or\n\
|
||||
- Enable the `prebuilt` feature to download from GitHub Releases."
|
||||
);
|
||||
|
||||
#[cfg(feature = "prebuilt")]
|
||||
{
|
||||
println!("{lib_var_name} not set, falling back to prebuilt download.");
|
||||
prebuilt::provision_library(circuit_name, lib_var_name)
|
||||
}
|
||||
},
|
||||
|lib_dir| {
|
||||
println!("Found {lib_var_name}, using local library at {lib_dir}.");
|
||||
let lib_dir_path = PathBuf::from(lib_dir);
|
||||
assert!(
|
||||
lib_dir_path.is_dir(),
|
||||
"The library directory specified in {lib_var_name} at {} does not exist.",
|
||||
lib_dir_path.display()
|
||||
);
|
||||
lib_dir_path
|
||||
},
|
||||
);
|
||||
|
||||
let lib_dir = lib_dir
|
||||
.to_str()
|
||||
.expect("Failed to convert the library directory path to a string");
|
||||
println!("cargo:rustc-env={lib_var_name}={lib_dir}");
|
||||
println!("cargo:rustc-link-search=native={lib_dir}");
|
||||
println!("cargo:rustc-link-lib=static={circuit_name}");
|
||||
println!("cargo:rustc-link-lib=stdc++");
|
||||
println!("cargo:rustc-link-lib=gmp");
|
||||
}
|
||||
16
rust/logos-blockchain-circuits-common/Cargo.toml
Normal file
16
rust/logos-blockchain-circuits-common/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-common"
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lbc-types = { workspace = true }
|
||||
1
rust/logos-blockchain-circuits-common/src/lib.rs
Normal file
1
rust/logos-blockchain-circuits-common/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod string;
|
||||
20
rust/logos-blockchain-circuits-common/src/string.rs
Normal file
20
rust/logos-blockchain-circuits-common/src/string.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use lbc_types::native::Error;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn as_null_terminated_string(string: &str) -> Result<std::ffi::CString, Error> {
|
||||
std::ffi::CString::new(string).map_err(|error| {
|
||||
Error::InvalidInput(Some(format!(
|
||||
"Could not convert string to CString: {error}"
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn path_as_null_terminated_string(path: &Path) -> Result<std::ffi::CString, Error> {
|
||||
let path = path.to_str().ok_or_else(|| {
|
||||
Error::InvalidInput(Some(format!(
|
||||
"Could not convert the path to a string: {}",
|
||||
path.display()
|
||||
)))
|
||||
})?;
|
||||
as_null_terminated_string(path)
|
||||
}
|
||||
23
rust/logos-blockchain-circuits-poc-sys/Cargo.toml
Normal file
23
rust/logos-blockchain-circuits-poc-sys/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-poc-sys"
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[features]
|
||||
prebuilt = ["lbc-build/prebuilt"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lbc-types = { workspace = true }
|
||||
lbc-common = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
lbc-build = { workspace = true }
|
||||
3
rust/logos-blockchain-circuits-poc-sys/build.rs
Normal file
3
rust/logos-blockchain-circuits-poc-sys/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
lbc_build::build("poc", "LBC_POC_LIB_DIR");
|
||||
}
|
||||
73
rust/logos-blockchain-circuits-poc-sys/sample.input.json
Normal file
73
rust/logos-blockchain-circuits-poc-sys/sample.input.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"secret_voucher": "967693750741252580129370741601438872183843430156721776754788549286651677750",
|
||||
"voucher_merkle_path": [
|
||||
"6760957519373942083753863818365891569838081322706287060861024958049616883872",
|
||||
"4465044690877673959379630031085790488013857563988547679987435075304500933954",
|
||||
"13324732284754601104005935378955314380888360214440369094293125852402660947587",
|
||||
"751846428059524824613704285163911088459476541213765124209950324431915959831",
|
||||
"6038709039063684132786699728641459669752757359588522148066703796251420937549",
|
||||
"13738028016996204322086995856054471548830485529018768524176769778055121664207",
|
||||
"3247811310761913519394659530300211882093244684976422241891466731923117641924",
|
||||
"17759434733520999094127756196564286982134377874670985981967107166244476114191",
|
||||
"10439394532189975251676889261553856687018976136540996547523529229452985841894",
|
||||
"21817985363519865032455212452700263411567232861782241553352701809413458230205",
|
||||
"12743546576539988493605660695948979780445141638209080027367248079788465306875",
|
||||
"10486283397124108182476342309962010457564415255711484724372810865359447030074",
|
||||
"7732396266725234558621644026839536297549144669187219414595824396993766503667",
|
||||
"9218727972992690804265624045300987755393869081123043258395582561748980225779",
|
||||
"12293828374871695333583884879696806078489804229410850142490615473351272368055",
|
||||
"15676114048570936960535525197542551243483740313061450270646442649470011330319",
|
||||
"7788186880839575813391082864142092937468972200299626575231867739594374584354",
|
||||
"16312033345360983679946394715036243256734413200471618477700490413711855126671",
|
||||
"16962284811957205674976016068974035759915296114616020584303314736345193043585",
|
||||
"7561654244528652857908285352009139941416843534230515440422770887337004738701",
|
||||
"1221817097944787806648540754395537787299626178709583354368288286078980967641",
|
||||
"13734831143243391544582579659353150156408343223164222563626930619372712282469",
|
||||
"8844967953129979365866630761540941039109023500226162691150639579280951984915",
|
||||
"2720862664779223685514929282617191922009465878195616364110482909635551933798",
|
||||
"4164638788145133427412986511346875737261315680675887710671119072340972066260",
|
||||
"9477784803841584355604716743687988183501535661924299108331302040811843685494",
|
||||
"19779338607502121804566093813321090012599307850902677285205344497085666699877",
|
||||
"14629589865216166173500986311834933690566596772333573563533435637260058354590",
|
||||
"16491383351556021779681173490637304596585835849620638208559205306534152597710",
|
||||
"2567887307252850771864398053039231796936889280823431337567399212882570032944",
|
||||
"17128149651933896729510402797195069638613831606426831356737111104282458862374",
|
||||
"21548396224793452403247607341264541760071256504082507925892356245056739977676"
|
||||
],
|
||||
"voucher_merkle_path_selectors": [
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1"
|
||||
],
|
||||
"mantle_tx_hash": "13403607866351080013115672688878717407774000351312443676099225335214329491209",
|
||||
"voucher_root": "20810875415353676096192834577269613981524168537821543897016159330974871397924"
|
||||
}
|
||||
12
rust/logos-blockchain-circuits-poc-sys/src/ffi.rs
Normal file
12
rust/logos-blockchain-circuits-poc-sys/src/ffi.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use lbc_types::ffi::{Bytes, Status, WitnessInput};
|
||||
use std::ffi::c_char;
|
||||
|
||||
unsafe extern "C" {
|
||||
pub fn poc_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;
|
||||
|
||||
pub fn poc_generate_witness_from_files(
|
||||
dat: *const c_char,
|
||||
inputs: *const c_char,
|
||||
output: *const c_char,
|
||||
) -> Status;
|
||||
}
|
||||
4
rust/logos-blockchain-circuits-poc-sys/src/lib.rs
Normal file
4
rust/logos-blockchain-circuits-poc-sys/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod ffi;
|
||||
pub mod native;
|
||||
|
||||
pub use native::{PocWitnessInput, generate_witness, generate_witness_from_files};
|
||||
82
rust/logos-blockchain-circuits-poc-sys/src/native.rs
Normal file
82
rust/logos-blockchain-circuits-poc-sys/src/native.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use crate::ffi::{poc_generate_witness, poc_generate_witness_from_files};
|
||||
use lbc_common::string::path_as_null_terminated_string;
|
||||
use lbc_types::{
|
||||
ffi,
|
||||
native::{Error, Witness},
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
static RAW_CIRCUIT_DAT: &[u8] =
|
||||
include_bytes!(concat!(env!("LBC_POC_LIB_DIR"), "/witness_generator.dat"));
|
||||
|
||||
pub struct PocDat;
|
||||
impl<'dat> lbc_types::CircuitDat<'dat> for PocDat {
|
||||
const DAT: &'dat [u8] = RAW_CIRCUIT_DAT;
|
||||
}
|
||||
|
||||
pub type PocWitnessInput<'dat> = lbc_types::CircuitWitnessInput<'dat, PocDat>;
|
||||
|
||||
pub fn generate_witness(input: &PocWitnessInput) -> Result<Witness, Error> {
|
||||
let ffi_input_guard = input.as_ffi();
|
||||
let ffi_input = ffi_input_guard.as_ref();
|
||||
|
||||
let mut ffi_output_bytes = ffi::Bytes::null();
|
||||
|
||||
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
|
||||
let status =
|
||||
unsafe { poc_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes) };
|
||||
|
||||
status.try_into().map(|()| Witness::from(ffi_output_bytes))
|
||||
}
|
||||
|
||||
pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) -> Result<(), Error> {
|
||||
let c_dat = path_as_null_terminated_string(dat)?;
|
||||
let c_inputs = path_as_null_terminated_string(inputs)?;
|
||||
let c_output = path_as_null_terminated_string(output)?;
|
||||
|
||||
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
|
||||
unsafe { poc_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr()) }
|
||||
.try_into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{PocWitnessInput, generate_witness, generate_witness_from_files};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
const ENV_VAR: &str = "LBC_POC_LIB_DIR";
|
||||
PathBuf::from(
|
||||
std::env::var(ENV_VAR).unwrap_or_else(
|
||||
|_| panic!("Environment variable '{ENV_VAR}' must be available, as provided by the build script."),
|
||||
)
|
||||
)
|
||||
});
|
||||
static INPUTS: LazyLock<PathBuf> =
|
||||
LazyLock::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("sample.input.json"));
|
||||
|
||||
#[test]
|
||||
fn test_generate_witness() {
|
||||
let dat = LIB_DIR.join("witness_generator");
|
||||
let witness_output_path = std::env::temp_dir().join("poc_test_witness.wtns");
|
||||
|
||||
generate_witness_from_files(&dat, &INPUTS, &witness_output_path)
|
||||
.expect("generate_witness_from_files failed.");
|
||||
|
||||
let inputs_json = std::fs::read_to_string(&*INPUTS)
|
||||
.unwrap_or_else(|_| panic!("Failed to read {}.", INPUTS.display()));
|
||||
|
||||
let input = PocWitnessInput::new(inputs_json)
|
||||
.expect("Failed to construct the input for the witness generator.");
|
||||
let output = generate_witness(&input).expect("generate_witness failed.");
|
||||
|
||||
let expected = std::fs::read(&witness_output_path).unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Failed to read the generated witness from {}.",
|
||||
witness_output_path.display()
|
||||
)
|
||||
});
|
||||
assert_eq!(output.as_ref().iter().as_slice(), expected.as_slice());
|
||||
}
|
||||
}
|
||||
23
rust/logos-blockchain-circuits-pol-sys/Cargo.toml
Normal file
23
rust/logos-blockchain-circuits-pol-sys/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-pol-sys"
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[features]
|
||||
prebuilt = ["lbc-build/prebuilt"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lbc-types = { workspace = true }
|
||||
lbc-common = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
lbc-build = { workspace = true }
|
||||
3
rust/logos-blockchain-circuits-pol-sys/build.rs
Normal file
3
rust/logos-blockchain-circuits-pol-sys/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
lbc_build::build("pol", "LBC_POL_LIB_DIR");
|
||||
}
|
||||
150
rust/logos-blockchain-circuits-pol-sys/sample.input.json
Normal file
150
rust/logos-blockchain-circuits-pol-sys/sample.input.json
Normal file
@ -0,0 +1,150 @@
|
||||
{
|
||||
"sl": "2",
|
||||
"epoch_nonce": "1",
|
||||
"t0": "2473484656031743130624528499274307172369787260057014856309956995191444674",
|
||||
"t1": "21888242732080995413138029684141064335057134963969188692069153164444508170606",
|
||||
"secret_key": "7329962581074531645140456897688060564526637306306408058828300122976166982059",
|
||||
"P_lead_part_one": "123456",
|
||||
"P_lead_part_two": "654321",
|
||||
"noteid_aged_path": [
|
||||
"15902188246945297660745639816877940054796159025125590367999255023125739397652",
|
||||
"17428337904521747122246156920806505766773506916800844590758448420881698740105",
|
||||
"468183280517368641419356975404050946184194985879608625527256681081514196098",
|
||||
"9857356446423834251015544624540902002861921286200857918125548693293771474746",
|
||||
"12530440301501032173254115146178387369899096696476921293807852624223441454699",
|
||||
"9102552235494849568056879081176958190502758901529745872149615078913093110367",
|
||||
"15332836703551879045647234301826436702072998048558632819831343618269234606372",
|
||||
"15952532935258781628726365207412031354751070204874462086915985737634285658345",
|
||||
"11617186336877516205132474707629582846966589234021946714155218394831358857247",
|
||||
"17080789484016787310502590647309822431255976143447625559555674333524647440067",
|
||||
"18659199795786635596293350923127416814662448928926239356418915092401949789788",
|
||||
"1043038124308436734336560531169206604082177989318077248264344526382690786982",
|
||||
"7003765854548265669971916203377800937290020471642328566366870448531962095529",
|
||||
"11050236989616267237111870236974875566108700565568898771969074233035618350002",
|
||||
"2533751737509759123516379686699492918377283972510738532508379695975052244036",
|
||||
"10434256768101250515198083337558660215927337348287005027389881302147240005154",
|
||||
"12837725658175272451154613854148629711893386915133752900810503335519991343655",
|
||||
"12700541049942924863612541852506887422731234828020365455762737916860175789704",
|
||||
"12573741914276908448045980903279034749900953112549139654805121785204580357207",
|
||||
"8968254178272762157895707330407008387111599719645052181828541862302266239216",
|
||||
"20742874131443474687782470845270548443698769223982267584726522628668308608112",
|
||||
"9999767371011565944639501141012524874493683597568729920926334390830396753704",
|
||||
"12374534369774902727257888918508979001911705274820078145646739679533754573424",
|
||||
"19268235150374693171101451101258052228702701088784125163210986110908874575894",
|
||||
"441332906538295507239051937515741879494109540079798934075454530577366571492",
|
||||
"6129618356747130372168909649376280133745354921100135443992798222259603841569",
|
||||
"4496649267081857811919738457357059245915720956181270410313546537907780142035",
|
||||
"12743126317937809671495985340192176235891732494688481786128621476821474665303",
|
||||
"901840713684703225385820874490383670490483483080770337662579043488775296023",
|
||||
"10927577986293549543779667277886325733953085688298112393252336467344863880365",
|
||||
"8473888800279268472161506886879723967558714367499595291224158750669832531158",
|
||||
"19721447853263860379579181356058567689083097845640785640187003258546563439277"
|
||||
],
|
||||
"noteid_aged_selectors": [
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1"
|
||||
],
|
||||
"ledger_aged": "9907496234164738674719754286318998202143315407023653151112941050435603056651",
|
||||
"note_tx_hash": "20223528014093812977541895123120747633533656837394263567369465802146525334433",
|
||||
"note_output_number": "422",
|
||||
"noteid_latest_path": [
|
||||
"20483380182942370599276460472822047910695963897520228620026114079480834642554",
|
||||
"8651317076561654292026377585519179675049184842398465650659084128411469650526",
|
||||
"21425771387649153085202676968883939741776698606005720713797165628391391510570",
|
||||
"2464861242004047676413225182531440736105723323417843370490252383311677571678",
|
||||
"19491453917823191068924688076595231671940471274477527498481756007196499447649",
|
||||
"1176748827065542272964701141107094149522420759289388172293118512335294635041",
|
||||
"3299427024440722918686537545360805925565544865914895921705713657483198282370",
|
||||
"8676294931486161402217736786136350680814737832309086766645947290346485301305",
|
||||
"1194490288177404655558854450331655377836115194134883251216647918413934872450",
|
||||
"15553436680567018414748245524365698672469393742981821478321757836296924702208",
|
||||
"18760606749355768642525698838451959355190742805724305319741610837135438843793",
|
||||
"6161496781920499484106873453663059897931985922037996995917393202282946916344",
|
||||
"17705630684705199458140820935591248964213782627117437314477744571443032304952",
|
||||
"9724274259568537436782348598156920528128138808555843188427494557472321468949",
|
||||
"5466817634746337628333298578810978989067001440642192446558436227084941093222",
|
||||
"16494041847547992223313095508652287702639424702153814725128657709203320143841",
|
||||
"6528170446718511127086652275105019639788731466250056396450984516917214341997",
|
||||
"6561500772488498465085378724738264583497130751949261757862310345373405719352",
|
||||
"3815120747999928230097864671072510355895072895139778010596771856349290188351",
|
||||
"17303101039105503728506358403584291694929820278543186462559922466312610206586",
|
||||
"6226574607729834489174079778279178763707817357653295885077105357079469092244",
|
||||
"21729366069495375565183890745946535138952895325166816652864384287210295488490",
|
||||
"14537848505494375072543340632196042321038883976220184774436389059255730709737",
|
||||
"9163027709361837575547371418304288816555790532858870081510396295711756310482",
|
||||
"6156464793863118277056215011382689237775042877662370243112733741034240082502",
|
||||
"20844456742401181559479512632286351148046075535736938039088626964972929711601",
|
||||
"2347402598418747187534401798976124993245365457072161587157981228855029862628",
|
||||
"20014696468373915559760277064758449323508513383406906656096464817687259375428",
|
||||
"8220804518985235671089333458601569928688446715891843624949744388799485342584",
|
||||
"20585877011082131167343660455058571070757301112744161576050391774335375778890",
|
||||
"16378233495401884641259747182647176572407610489279387832117800731619897286201",
|
||||
"14220045659305316526516794332224144375368271853520372229536276752477675518408"
|
||||
],
|
||||
"noteid_latest_selectors": [
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1"
|
||||
],
|
||||
"ledger_latest": "19194142281236793845067321500021419635169885917260820016897850403558817637963",
|
||||
"v": "3"
|
||||
}
|
||||
12
rust/logos-blockchain-circuits-pol-sys/src/ffi.rs
Normal file
12
rust/logos-blockchain-circuits-pol-sys/src/ffi.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use lbc_types::ffi::{Bytes, Status, WitnessInput};
|
||||
use std::ffi::c_char;
|
||||
|
||||
unsafe extern "C" {
|
||||
pub fn pol_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;
|
||||
|
||||
pub fn pol_generate_witness_from_files(
|
||||
dat: *const c_char,
|
||||
inputs: *const c_char,
|
||||
output: *const c_char,
|
||||
) -> Status;
|
||||
}
|
||||
4
rust/logos-blockchain-circuits-pol-sys/src/lib.rs
Normal file
4
rust/logos-blockchain-circuits-pol-sys/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod ffi;
|
||||
pub mod native;
|
||||
|
||||
pub use native::{PolWitnessInput, generate_witness, generate_witness_from_files};
|
||||
82
rust/logos-blockchain-circuits-pol-sys/src/native.rs
Normal file
82
rust/logos-blockchain-circuits-pol-sys/src/native.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use crate::ffi::{pol_generate_witness, pol_generate_witness_from_files};
|
||||
use lbc_common::string::path_as_null_terminated_string;
|
||||
use lbc_types::{
|
||||
ffi,
|
||||
native::{Error, Witness},
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
static RAW_CIRCUIT_DAT: &[u8] =
|
||||
include_bytes!(concat!(env!("LBC_POL_LIB_DIR"), "/witness_generator.dat"));
|
||||
|
||||
pub struct PolDat;
|
||||
impl<'dat> lbc_types::CircuitDat<'dat> for PolDat {
|
||||
const DAT: &'dat [u8] = RAW_CIRCUIT_DAT;
|
||||
}
|
||||
|
||||
pub type PolWitnessInput<'dat> = lbc_types::CircuitWitnessInput<'dat, PolDat>;
|
||||
|
||||
pub fn generate_witness(input: &PolWitnessInput) -> Result<Witness, Error> {
|
||||
let ffi_input_guard = input.as_ffi();
|
||||
let ffi_input = ffi_input_guard.as_ref();
|
||||
|
||||
let mut ffi_output_bytes = ffi::Bytes::null();
|
||||
|
||||
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
|
||||
let status =
|
||||
unsafe { pol_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes) };
|
||||
|
||||
status.try_into().map(|()| Witness::from(ffi_output_bytes))
|
||||
}
|
||||
|
||||
pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) -> Result<(), Error> {
|
||||
let c_dat = path_as_null_terminated_string(dat)?;
|
||||
let c_inputs = path_as_null_terminated_string(inputs)?;
|
||||
let c_output = path_as_null_terminated_string(output)?;
|
||||
|
||||
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
|
||||
unsafe { pol_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr()) }
|
||||
.try_into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{PolWitnessInput, generate_witness, generate_witness_from_files};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
const ENV_VAR: &str = "LBC_POL_LIB_DIR";
|
||||
PathBuf::from(
|
||||
std::env::var(ENV_VAR).unwrap_or_else(
|
||||
|_| panic!("Environment variable '{ENV_VAR}' must be available, as provided by the build script."),
|
||||
)
|
||||
)
|
||||
});
|
||||
static INPUTS: LazyLock<PathBuf> =
|
||||
LazyLock::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("sample.input.json"));
|
||||
|
||||
#[test]
|
||||
fn test_generate_witness() {
|
||||
let dat = LIB_DIR.join("witness_generator");
|
||||
let witness_output_path = std::env::temp_dir().join("pol_test_witness.wtns");
|
||||
|
||||
generate_witness_from_files(&dat, &INPUTS, &witness_output_path)
|
||||
.expect("generate_witness_from_files failed.");
|
||||
|
||||
let inputs_json = std::fs::read_to_string(&*INPUTS)
|
||||
.unwrap_or_else(|_| panic!("Failed to read {}.", INPUTS.display()));
|
||||
|
||||
let input = PolWitnessInput::new(inputs_json)
|
||||
.expect("Failed to construct the input for the witness generator.");
|
||||
let output = generate_witness(&input).expect("generate_witness failed.");
|
||||
|
||||
let expected = std::fs::read(&witness_output_path).unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Failed to read the generated witness from {}.",
|
||||
witness_output_path.display()
|
||||
)
|
||||
});
|
||||
assert_eq!(output.as_ref().iter().as_slice(), expected.as_slice());
|
||||
}
|
||||
}
|
||||
23
rust/logos-blockchain-circuits-poq-sys/Cargo.toml
Normal file
23
rust/logos-blockchain-circuits-poq-sys/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-poq-sys"
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[features]
|
||||
prebuilt = ["lbc-build/prebuilt"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lbc-types = { workspace = true }
|
||||
lbc-common = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
lbc-build = { workspace = true }
|
||||
3
rust/logos-blockchain-circuits-poq-sys/build.rs
Normal file
3
rust/logos-blockchain-circuits-poq-sys/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
lbc_build::build("poq", "LBC_POQ_LIB_DIR");
|
||||
}
|
||||
132
rust/logos-blockchain-circuits-poq-sys/sample.input.json
Normal file
132
rust/logos-blockchain-circuits-poq-sys/sample.input.json
Normal file
@ -0,0 +1,132 @@
|
||||
{
|
||||
"session": "1",
|
||||
"core_quota": "10",
|
||||
"leader_quota": "5",
|
||||
"core_root": "20423847801203321296654759690878714805328777188198550442842378955293864405749",
|
||||
"pol_ledger_aged": "17903920406556048980238705683215862296511171897974321387437239009873416173088",
|
||||
"K_part_one": "123456",
|
||||
"K_part_two": "654321",
|
||||
"selector": "0",
|
||||
"index": "4",
|
||||
"core_sk": "9648814259696994178754585280937762562521917479862309330976828088416086689502",
|
||||
"core_path": [
|
||||
"7444981793259323545028230817540266139574655346498587207322690091155864366514",
|
||||
"11906618682557735136285409970678605865823718647884839058358264586062323572931",
|
||||
"20134132405688011859463119692951856666179032704702165461712292610201307937895",
|
||||
"14957940720199233077855574470291237736607251243547208306826060526364053594567",
|
||||
"9960019677323356900045391326995069522689045788302673979918902013710931552405",
|
||||
"66857460143066791244205132003829555578944395751024287435105865077587183768",
|
||||
"9684190057075151027164519297536804034845411696380043986044825589786854843890",
|
||||
"5454398284364625202375600088042852298143548338598297694708920725120268102172",
|
||||
"17717838934596276392301608861658238780702831838416312046180761451761658981677",
|
||||
"21049060929819155971068746329904761210986436808741330971979776532239897765447",
|
||||
"11774149665086408677974469133186402228920447314607286251417731337331983592621",
|
||||
"20730401134454070553472357967443459347591806294042271432905369723302561196146",
|
||||
"8683835652829558567596368905844156962511421729430671198119438457363223237488",
|
||||
"15354188356303619925782257044335868802108846851399355235348014093341533049042",
|
||||
"4726038353749363201132655543916148764086757634128462972437143285566298790278",
|
||||
"19793785327783426164764238122458972627129812758755648364664517341770465698137",
|
||||
"12144554112696250636735897359535254161697584560941692171669941649860599557215",
|
||||
"4391930156296016129347969147731784916200749354398548728573386759785083449305",
|
||||
"9056244932796998900758180921717949733339642790698415152308909239074793689860",
|
||||
"20440861423381563032522290464977155181939164858308810772959774388792060977834"
|
||||
],
|
||||
"core_path_selectors": [
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1"
|
||||
],
|
||||
"pol_sl": "2999142337",
|
||||
"pol_epoch_nonce": "13416107872788342879859909752417297479970876884105393946206193406636245124924",
|
||||
"pol_t0": "148409079361904587837471709956458430342187235603420891378597419711486680",
|
||||
"pol_t1": "21888242871336145414933615591437256729835795974444825699352339602896135814447",
|
||||
"pol_secret_key": "5888730225944530149138538772959785628943021630629194621324636699030154327779",
|
||||
"pol_noteid_path": [
|
||||
"11417212955939342484156122492131731680470736064572423108264714804692982132423",
|
||||
"13195529687976077417120457189120231305870945642160590995096417385531885506527",
|
||||
"8472612035444494025196025434618086294389115909303446215474787216226075733233",
|
||||
"4395544485586958768290328184233580023235668872384703046186144832197262227824",
|
||||
"4155097203117131499585729150758272768367941952959383568978188417941807061285",
|
||||
"12408098106443635130911956104856030560309651099061156514970962447957027050139",
|
||||
"18743723426188623742373733557975920292757537418376825891131826727792647674843",
|
||||
"8921759404097162857845142647448014820935511584403450140750072994549272153730",
|
||||
"12780803834914504736250867272694468211504307499239030290058679926157641539231",
|
||||
"14426829036224566782069722269326129726234814130810124541609677896636347739469",
|
||||
"12104693267449791844517047312768375964966170218283608605832423892888932116836",
|
||||
"4883118865130876989815011894870188012768758733041802381045504888060618022896",
|
||||
"221076344526264664133449802750892395792062472746642224588395874880886057862",
|
||||
"5113214819332200669368049090534645222011919607097424838023324847441692662817",
|
||||
"11190105598795402691316927391391967636268949446132854344954730333558274776561",
|
||||
"9497071318258212130830107535590335197992746719505860281792486969560303727415",
|
||||
"748420254289718676536943619836584348410332952487466816579920043963946022247",
|
||||
"14115148735545746869495305176487552481901196697644225252711231121645192222529",
|
||||
"9825912699605171279245430402178700385570068146465368260071935364769450924475",
|
||||
"1501769250930508362584740947030050914124963948804793138968307230445384260381",
|
||||
"17449384761389191557925767178974603169885098072345898391638302374310429932515",
|
||||
"15254499277889636076581272515864557232200527228506352325296439482258130354292",
|
||||
"17609649632230164263025759476016886422378093160688512447628349616375377913864",
|
||||
"3796675673265260264289049510567646443858253346231355244420810954931342727796",
|
||||
"16421896950452608279534605320939669191650110271813875344999112106538557831552",
|
||||
"17833913909116979902116409442832814514923484644816639363063290974377083565699",
|
||||
"6674420083709581276404439792277275401604929658229769714363091874557852768901",
|
||||
"413703733576599351434912508015408034175577472292919474661639467491474199758",
|
||||
"8269883007022448705723402393227587978527160373548295017073655056451421211755",
|
||||
"2524601535002894286006232081527402693925618141420537796447547436812892177839",
|
||||
"18128917825606990579294624696080518601859437342124614427642120271129736700878",
|
||||
"20950332433104838321486108855942309235493780674594737746438717221993421294744"
|
||||
],
|
||||
"pol_noteid_path_selectors": [
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0",
|
||||
"1",
|
||||
"1",
|
||||
"1",
|
||||
"0",
|
||||
"0"
|
||||
],
|
||||
"pol_note_tx_hash": "10190023498178194208361021687460995025878664681917212352967702284591462728108",
|
||||
"pol_note_output_number": "449",
|
||||
"pol_note_value": "50"
|
||||
}
|
||||
12
rust/logos-blockchain-circuits-poq-sys/src/ffi.rs
Normal file
12
rust/logos-blockchain-circuits-poq-sys/src/ffi.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use lbc_types::ffi::{Bytes, Status, WitnessInput};
|
||||
use std::ffi::c_char;
|
||||
|
||||
unsafe extern "C" {
|
||||
pub fn poq_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;
|
||||
|
||||
pub fn poq_generate_witness_from_files(
|
||||
dat: *const c_char,
|
||||
inputs: *const c_char,
|
||||
output: *const c_char,
|
||||
) -> Status;
|
||||
}
|
||||
4
rust/logos-blockchain-circuits-poq-sys/src/lib.rs
Normal file
4
rust/logos-blockchain-circuits-poq-sys/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod ffi;
|
||||
pub mod native;
|
||||
|
||||
pub use native::{PoqWitnessInput, generate_witness, generate_witness_from_files};
|
||||
82
rust/logos-blockchain-circuits-poq-sys/src/native.rs
Normal file
82
rust/logos-blockchain-circuits-poq-sys/src/native.rs
Normal file
@ -0,0 +1,82 @@
|
||||
use crate::ffi::{poq_generate_witness, poq_generate_witness_from_files};
|
||||
use lbc_common::string::path_as_null_terminated_string;
|
||||
use lbc_types::{
|
||||
ffi,
|
||||
native::{Error, Witness},
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
static RAW_CIRCUIT_DAT: &[u8] =
|
||||
include_bytes!(concat!(env!("LBC_POQ_LIB_DIR"), "/witness_generator.dat"));
|
||||
|
||||
pub struct PoqDat;
|
||||
impl<'dat> lbc_types::CircuitDat<'dat> for PoqDat {
|
||||
const DAT: &'dat [u8] = RAW_CIRCUIT_DAT;
|
||||
}
|
||||
|
||||
pub type PoqWitnessInput<'dat> = lbc_types::CircuitWitnessInput<'dat, PoqDat>;
|
||||
|
||||
pub fn generate_witness(input: &PoqWitnessInput) -> Result<Witness, Error> {
|
||||
let ffi_input_guard = input.as_ffi();
|
||||
let ffi_input = ffi_input_guard.as_ref();
|
||||
|
||||
let mut ffi_output_bytes = ffi::Bytes::null();
|
||||
|
||||
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
|
||||
let status =
|
||||
unsafe { poq_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes) };
|
||||
|
||||
status.try_into().map(|()| Witness::from(ffi_output_bytes))
|
||||
}
|
||||
|
||||
pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) -> Result<(), Error> {
|
||||
let c_dat = path_as_null_terminated_string(dat)?;
|
||||
let c_inputs = path_as_null_terminated_string(inputs)?;
|
||||
let c_output = path_as_null_terminated_string(output)?;
|
||||
|
||||
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
|
||||
unsafe { poq_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr()) }
|
||||
.try_into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{PoqWitnessInput, generate_witness, generate_witness_from_files};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
const ENV_VAR: &str = "LBC_POQ_LIB_DIR";
|
||||
PathBuf::from(
|
||||
std::env::var(ENV_VAR).unwrap_or_else(
|
||||
|_| panic!("Environment variable '{ENV_VAR}' must be available, as provided by the build script."),
|
||||
)
|
||||
)
|
||||
});
|
||||
static INPUTS: LazyLock<PathBuf> =
|
||||
LazyLock::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("sample.input.json"));
|
||||
|
||||
#[test]
|
||||
fn test_generate_witness() {
|
||||
let dat = LIB_DIR.join("witness_generator");
|
||||
let witness_output_path = std::env::temp_dir().join("poq_test_witness.wtns");
|
||||
|
||||
generate_witness_from_files(&dat, &INPUTS, &witness_output_path)
|
||||
.expect("generate_witness_from_files failed.");
|
||||
|
||||
let inputs_json = std::fs::read_to_string(&*INPUTS)
|
||||
.unwrap_or_else(|_| panic!("Failed to read {}.", INPUTS.display()));
|
||||
|
||||
let input = PoqWitnessInput::new(inputs_json)
|
||||
.expect("Failed to construct the input for the witness generator.");
|
||||
let output = generate_witness(&input).expect("generate_witness failed.");
|
||||
|
||||
let expected = std::fs::read(&witness_output_path).unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Failed to read the generated witness from {}.",
|
||||
witness_output_path.display()
|
||||
)
|
||||
});
|
||||
assert_eq!(output.as_ref().iter().as_slice(), expected.as_slice());
|
||||
}
|
||||
}
|
||||
23
rust/logos-blockchain-circuits-signature-sys/Cargo.toml
Normal file
23
rust/logos-blockchain-circuits-signature-sys/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-signature-sys"
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[features]
|
||||
prebuilt = ["lbc-build/prebuilt"]
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
lbc-types = { workspace = true }
|
||||
lbc-common = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
lbc-build = { workspace = true }
|
||||
3
rust/logos-blockchain-circuits-signature-sys/build.rs
Normal file
3
rust/logos-blockchain-circuits-signature-sys/build.rs
Normal file
@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
lbc_build::build("signature", "LBC_SIGNATURE_LIB_DIR");
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"secret_keys": [
|
||||
"4098660825806322106084917185877010365998862351268353704832317909929107002180",
|
||||
"2596177389886188281596978093959690371159914261946677318098645747664853545334",
|
||||
"19330846001036806632630691788566327913635233354660529061620854887613210243052",
|
||||
"13718551754506405197443815435437300347734571755567740886306457364649402186553",
|
||||
"6204148614304430226861132556010829917345597652038502840597675273498043144451",
|
||||
"15755521481655998437707437556070134762137394314366394920968545131987543981102",
|
||||
"11434634292101129704779207098617082796007566344360047961971399449469942728547",
|
||||
"1091020027659842297575459412975398408818486151826195655315644888474716868332",
|
||||
"1661418073407206326237403014548147762215859087746801732040113509361531462500",
|
||||
"20628813409264227566051422798099856805018133740192165327801956537938406198081",
|
||||
"327965494390850983495190187405149071612762485615773297559993697718924431952",
|
||||
"8359983131932599018580929850473426740353652682335586902534879079235060354372",
|
||||
"6001997642641265677487124391062970262114562733679341855865413164728827534876",
|
||||
"4322142471707950388783633694420765022063880822490308569932169051464371677687",
|
||||
"5199317950973283137516788124063301811586747068671537026189099053918194655518",
|
||||
"4878043903155423406402270755752662933424125800765439117197056070420025827007",
|
||||
"18383023798211595062002947539653067956198613952091768346565349157965661370879",
|
||||
"16785909593043203210549043820115025237749244647904538613296130098899332712430",
|
||||
"15467980282061694469300695749385517926850361484529888884367690782358434467841",
|
||||
"10874762142964436895350252025677859023454508059151894039076338836998263676047",
|
||||
"13448584667305124010536281145122646499463567394753279948588189274394145173068",
|
||||
"10163232510156788884730739506862867831894904471198701058400872517735368970791",
|
||||
"5220666930634917579087865848579036529755356054528301534514932964322747989260",
|
||||
"19950242287192592205940905658928387310191814871825582446129402931984520537085",
|
||||
"11493441223791405874036262554540342214352159322279505543922710193330606461053",
|
||||
"13970669468715193555525716515867031876612509505528078470569781677204432503054",
|
||||
"2617218434049077957942178980979194560061213987929479929629616784596361883755",
|
||||
"10262860452995012573731922300160498681285885199421850052844703904968888647633",
|
||||
"21818248483534286893890935091845502181077194830723832321102213680624411710883",
|
||||
"7587080455062894070835842475066387476154828963596866773497564550910530217948",
|
||||
"2067356816097510189886893732466232519758829910334449764538259630587857195500",
|
||||
"582466643052618756521674522356117975734709415984615399233198386186277496483"
|
||||
],
|
||||
"msg": "15376625227674870759661626327809807256501138528181290032321552536459910806161"
|
||||
}
|
||||
12
rust/logos-blockchain-circuits-signature-sys/src/ffi.rs
Normal file
12
rust/logos-blockchain-circuits-signature-sys/src/ffi.rs
Normal file
@ -0,0 +1,12 @@
|
||||
use lbc_types::ffi::{Bytes, Status, WitnessInput};
|
||||
use std::ffi::c_char;
|
||||
|
||||
unsafe extern "C" {
|
||||
pub fn signature_generate_witness(input: *const WitnessInput, output: *mut Bytes) -> Status;
|
||||
|
||||
pub fn signature_generate_witness_from_files(
|
||||
dat: *const c_char,
|
||||
inputs: *const c_char,
|
||||
output: *const c_char,
|
||||
) -> Status;
|
||||
}
|
||||
4
rust/logos-blockchain-circuits-signature-sys/src/lib.rs
Normal file
4
rust/logos-blockchain-circuits-signature-sys/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod ffi;
|
||||
pub mod native;
|
||||
|
||||
pub use native::{SignatureWitnessInput, generate_witness, generate_witness_from_files};
|
||||
87
rust/logos-blockchain-circuits-signature-sys/src/native.rs
Normal file
87
rust/logos-blockchain-circuits-signature-sys/src/native.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use crate::ffi::{signature_generate_witness, signature_generate_witness_from_files};
|
||||
use lbc_common::string::path_as_null_terminated_string;
|
||||
use lbc_types::{
|
||||
ffi,
|
||||
native::{Error, Witness},
|
||||
};
|
||||
use std::path::Path;
|
||||
|
||||
static RAW_CIRCUIT_DAT: &[u8] = include_bytes!(concat!(
|
||||
env!("LBC_SIGNATURE_LIB_DIR"),
|
||||
"/witness_generator.dat"
|
||||
));
|
||||
|
||||
pub struct SignatureDat;
|
||||
impl<'dat> lbc_types::CircuitDat<'dat> for SignatureDat {
|
||||
const DAT: &'dat [u8] = RAW_CIRCUIT_DAT;
|
||||
}
|
||||
|
||||
pub type SignatureWitnessInput<'dat> = lbc_types::CircuitWitnessInput<'dat, SignatureDat>;
|
||||
|
||||
pub fn generate_witness(input: &SignatureWitnessInput) -> Result<Witness, Error> {
|
||||
let ffi_input_guard = input.as_ffi();
|
||||
let ffi_input = ffi_input_guard.as_ref();
|
||||
|
||||
let mut ffi_output_bytes = ffi::Bytes::null();
|
||||
|
||||
// SAFETY: ffi_input is a valid pointer and ffi_output_bytes is a locally initialized null Bytes.
|
||||
let status = unsafe {
|
||||
signature_generate_witness(std::ptr::from_ref(ffi_input), &raw mut ffi_output_bytes)
|
||||
};
|
||||
|
||||
status.try_into().map(|()| Witness::from(ffi_output_bytes))
|
||||
}
|
||||
|
||||
pub fn generate_witness_from_files(dat: &Path, inputs: &Path, output: &Path) -> Result<(), Error> {
|
||||
let c_dat = path_as_null_terminated_string(dat)?;
|
||||
let c_inputs = path_as_null_terminated_string(inputs)?;
|
||||
let c_output = path_as_null_terminated_string(output)?;
|
||||
|
||||
// SAFETY: c_dat, c_inputs, and c_output are valid null-terminated C strings for the duration of the call.
|
||||
unsafe {
|
||||
signature_generate_witness_from_files(c_dat.as_ptr(), c_inputs.as_ptr(), c_output.as_ptr())
|
||||
}
|
||||
.try_into()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{SignatureWitnessInput, generate_witness, generate_witness_from_files};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static LIB_DIR: LazyLock<PathBuf> = LazyLock::new(|| {
|
||||
const ENV_VAR: &str = "LBC_SIGNATURE_LIB_DIR";
|
||||
PathBuf::from(
|
||||
std::env::var(ENV_VAR).unwrap_or_else(
|
||||
|_| panic!("Environment variable '{ENV_VAR}' must be available, as provided by the build script."),
|
||||
)
|
||||
)
|
||||
});
|
||||
static INPUTS: LazyLock<PathBuf> =
|
||||
LazyLock::new(|| PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("sample.input.json"));
|
||||
|
||||
#[test]
|
||||
fn test_generate_witness() {
|
||||
let dat = LIB_DIR.join("witness_generator");
|
||||
let witness_output_path = std::env::temp_dir().join("signature_test_witness.wtns");
|
||||
|
||||
generate_witness_from_files(&dat, &INPUTS, &witness_output_path)
|
||||
.expect("generate_witness_from_files failed.");
|
||||
|
||||
let inputs_json = std::fs::read_to_string(&*INPUTS)
|
||||
.unwrap_or_else(|_| panic!("Failed to read {}.", INPUTS.display()));
|
||||
|
||||
let input = SignatureWitnessInput::new(inputs_json)
|
||||
.expect("Failed to construct the input for the witness generator.");
|
||||
let output = generate_witness(&input).expect("generate_witness failed.");
|
||||
|
||||
let expected = std::fs::read(&witness_output_path).unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Failed to read the generated witness from {}.",
|
||||
witness_output_path.display()
|
||||
)
|
||||
});
|
||||
assert_eq!(output.as_ref().iter().as_slice(), expected.as_slice());
|
||||
}
|
||||
}
|
||||
72
rust/logos-blockchain-circuits-types/Cargo.lock
generated
Normal file
72
rust/logos-blockchain-circuits-types/Cargo.lock
generated
Normal file
@ -0,0 +1,72 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.185"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
||||
|
||||
[[package]]
|
||||
name = "logos-blockchain-circuits-types"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
17
rust/logos-blockchain-circuits-types/Cargo.toml
Normal file
17
rust/logos-blockchain-circuits-types/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
||||
[package]
|
||||
name = "logos-blockchain-circuits-types"
|
||||
categories.workspace = true
|
||||
description.workspace = true
|
||||
edition.workspace = true
|
||||
keywords.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
bytes = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
64
rust/logos-blockchain-circuits-types/src/ffi/bytes.rs
Normal file
64
rust/logos-blockchain-circuits-types/src/ffi/bytes.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use libc::free;
|
||||
|
||||
mod inner {
|
||||
#[repr(C)]
|
||||
pub struct Buffer<T> {
|
||||
pub data: T,
|
||||
pub size: usize,
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> inner::Buffer<*const T> {
|
||||
pub const fn null() -> Self {
|
||||
Self {
|
||||
data: std::ptr::null(),
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> inner::Buffer<*mut T> {
|
||||
pub const fn null() -> Self {
|
||||
Self {
|
||||
data: std::ptr::null_mut(),
|
||||
size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Owned byte buffer returned by the C witness generator functions.
|
||||
///
|
||||
/// The inner `data` pointer must be null-initialized. It's heap-allocated by the C side and must be
|
||||
/// freed with [`free_bytes`] after use.
|
||||
pub type Bytes = inner::Buffer<*mut u8>;
|
||||
|
||||
/// Read-only byte slice passed into the C witness generator functions.
|
||||
pub type ConstBytes = inner::Buffer<*const u8>;
|
||||
|
||||
/// Frees the data buffer inside a [`Bytes`] struct allocated by the C API.
|
||||
///
|
||||
/// Only the inner data buffer is freed, not the struct itself, since the latter is managed by the
|
||||
/// caller.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `bytes`: A pointer to a [`Bytes`] struct whose data buffer was allocated by the C API and
|
||||
/// needs to be freed.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Dereferences raw pointers.
|
||||
pub unsafe fn free_bytes(bytes: *mut Bytes) {
|
||||
if bytes.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
// SAFETY: `bytes` is non-null (checked above).
|
||||
let bytes = unsafe { &mut *bytes };
|
||||
if !bytes.data.is_null() {
|
||||
// SAFETY: `bytes.data` is non-null (checked above).
|
||||
unsafe { free(bytes.data.cast::<libc::c_void>()) };
|
||||
}
|
||||
bytes.data = std::ptr::null_mut();
|
||||
bytes.size = 0;
|
||||
}
|
||||
12
rust/logos-blockchain-circuits-types/src/ffi/mod.rs
Normal file
12
rust/logos-blockchain-circuits-types/src/ffi/mod.rs
Normal file
@ -0,0 +1,12 @@
|
||||
//! Raw `#[repr(C)]` types that mirror the C witness generator API.
|
||||
//!
|
||||
//! These types map directly to the C header structs and are used at the FFI boundary. Prefer the
|
||||
//! wrappers in [`crate::native`] for ordinary Rust code.
|
||||
|
||||
pub mod bytes;
|
||||
pub mod status;
|
||||
pub mod witness_input;
|
||||
|
||||
pub use bytes::{Bytes, ConstBytes, free_bytes};
|
||||
pub use status::Status;
|
||||
pub use witness_input::WitnessInput;
|
||||
55
rust/logos-blockchain-circuits-types/src/ffi/status.rs
Normal file
55
rust/logos-blockchain-circuits-types/src/ffi/status.rs
Normal file
@ -0,0 +1,55 @@
|
||||
use std::ffi::c_char;
|
||||
|
||||
/// Status codes for C API functions.
|
||||
#[derive(PartialEq, Eq)] // Enables comparisons with named constants.
|
||||
#[repr(transparent)]
|
||||
pub struct Code(pub i32);
|
||||
|
||||
impl Code {
|
||||
pub const OK: Self = Self(0);
|
||||
pub const DYN_ERROR: Self = Self(1);
|
||||
pub const INVALID_INPUT: Self = Self(2);
|
||||
pub const OUT_OF_MEMORY: Self = Self(3);
|
||||
|
||||
#[must_use]
|
||||
pub fn is_ok(&self) -> bool {
|
||||
self == &Self::OK
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_error(&self) -> bool {
|
||||
!self.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// Status reporting structure for C API functions.
|
||||
#[repr(C)]
|
||||
pub struct Status {
|
||||
pub code: Code,
|
||||
pub message: [c_char; 256],
|
||||
}
|
||||
|
||||
impl Status {
|
||||
#[must_use]
|
||||
pub const fn ok() -> Self {
|
||||
Self {
|
||||
code: Code::OK,
|
||||
message: [0; 256],
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_ok(&self) -> bool {
|
||||
self.code.is_ok()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_error(&self) -> bool {
|
||||
self.code.is_error()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn has_message(&self) -> bool {
|
||||
self.message[0] != 0
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
use crate::ffi::ConstBytes;
|
||||
use std::ffi::c_char;
|
||||
|
||||
/// Input to a witness generator function.
|
||||
///
|
||||
/// Both pointers must remain valid for the duration of the C call.
|
||||
#[repr(C)]
|
||||
pub struct WitnessInput {
|
||||
/// The circuit data file contents.
|
||||
pub dat: ConstBytes,
|
||||
/// Null-terminated JSON string containing the circuit inputs.
|
||||
pub inputs_json: *const c_char,
|
||||
}
|
||||
10
rust/logos-blockchain-circuits-types/src/lib.rs
Normal file
10
rust/logos-blockchain-circuits-types/src/lib.rs
Normal file
@ -0,0 +1,10 @@
|
||||
//! Raw FFI types and Rust-safe wrappers for the witness generator C API.
|
||||
//!
|
||||
//! The [`ffi`] module contains `#[repr(C)]` types that mirror the C headers directly. The
|
||||
//! [`native`] module re-exposes those through idiomatic Rust types that own their memory and
|
||||
//! convert FFI return values into [`Result`]s.
|
||||
|
||||
pub mod ffi;
|
||||
pub mod native;
|
||||
|
||||
pub use native::{CircuitDat, CircuitWitnessInput, Error};
|
||||
@ -0,0 +1,30 @@
|
||||
use crate::native::{Error, WitnessInput};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
|
||||
pub trait CircuitDat<'dat> {
|
||||
const DAT: &'dat [u8];
|
||||
}
|
||||
|
||||
pub struct CircuitWitnessInput<'dat, Dat> {
|
||||
inner: WitnessInput<'dat>,
|
||||
_phantom: PhantomData<Dat>,
|
||||
}
|
||||
|
||||
impl<'dat, Dat: CircuitDat<'dat>> CircuitWitnessInput<'dat, Dat> {
|
||||
pub fn new(inputs_json: String) -> Result<Self, Error> {
|
||||
let inner = WitnessInput::new(Dat::DAT, inputs_json)?;
|
||||
Ok(Self {
|
||||
inner,
|
||||
_phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'dat, Dat> Deref for CircuitWitnessInput<'dat, Dat> {
|
||||
type Target = WitnessInput<'dat>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
13
rust/logos-blockchain-circuits-types/src/native/mod.rs
Normal file
13
rust/logos-blockchain-circuits-types/src/native/mod.rs
Normal file
@ -0,0 +1,13 @@
|
||||
//! Rust-safe wrappers around the FFI types.
|
||||
//!
|
||||
//! Use them in preference to the types in [`crate::ffi`].
|
||||
|
||||
pub mod circuit_witness_input;
|
||||
pub mod status;
|
||||
pub mod witness;
|
||||
pub mod witness_input;
|
||||
|
||||
pub use circuit_witness_input::{CircuitDat, CircuitWitnessInput};
|
||||
pub use status::{Error, Result};
|
||||
pub use witness::Witness;
|
||||
pub use witness_input::WitnessInput;
|
||||
52
rust/logos-blockchain-circuits-types/src/native/status.rs
Normal file
52
rust/logos-blockchain-circuits-types/src/native/status.rs
Normal file
@ -0,0 +1,52 @@
|
||||
use crate::ffi::status::Code as FfiStatusCode;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt::Display;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
/// Error returned when a witness generator call does not succeed.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
InvalidInput(Option<String>),
|
||||
OutOfMemory(Option<String>),
|
||||
Other(Option<String>),
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let (kind, message) = match self {
|
||||
Self::InvalidInput(msg) => ("Invalid input", msg),
|
||||
Self::OutOfMemory(msg) => ("Out of memory", msg),
|
||||
Self::Other(msg) => ("Other error", msg),
|
||||
};
|
||||
match message {
|
||||
Some(message) => write!(f, "{kind}: {message}"),
|
||||
None => write!(f, "{kind}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<crate::ffi::Status> for () {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(status: crate::ffi::Status) -> Result<()> {
|
||||
let message: Option<String> = status.has_message().then(|| {
|
||||
// SAFETY: `status.message` is non-empty (checked by `has_message()`) and null-terminated as guaranteed by the C API.
|
||||
let status_message = unsafe { CStr::from_ptr(status.message.as_ptr()) };
|
||||
status_message.to_string_lossy().into_owned()
|
||||
});
|
||||
|
||||
match status.code {
|
||||
FfiStatusCode::OK => Ok(()),
|
||||
FfiStatusCode::DYN_ERROR => Err(Error::Other(message)),
|
||||
FfiStatusCode::INVALID_INPUT => Err(Error::InvalidInput(message)),
|
||||
FfiStatusCode::OUT_OF_MEMORY => Err(Error::OutOfMemory(message)),
|
||||
other => Err(Error::Other(Some(format!(
|
||||
"Unknown status code: {}",
|
||||
other.0
|
||||
)))),
|
||||
}
|
||||
}
|
||||
}
|
||||
34
rust/logos-blockchain-circuits-types/src/native/witness.rs
Normal file
34
rust/logos-blockchain-circuits-types/src/native/witness.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::ffi;
|
||||
|
||||
/// Byte buffer
|
||||
///
|
||||
/// When constructing from [`From<ffi::Bytes>`], it takes ownership of the underlying value and
|
||||
/// frees it.
|
||||
pub struct Witness(bytes::Bytes);
|
||||
|
||||
impl From<bytes::Bytes> for Witness {
|
||||
fn from(bytes: bytes::Bytes) -> Self {
|
||||
Self(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<bytes::Bytes> for Witness {
|
||||
fn as_ref(&self) -> &bytes::Bytes {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ffi::Bytes> for Witness {
|
||||
fn from(mut ffi_value: ffi::Bytes) -> Self {
|
||||
let vec = if ffi_value.size == 0 || ffi_value.data.is_null() {
|
||||
Vec::new()
|
||||
} else {
|
||||
// SAFETY: `ffi_value.data` is non-null and `ffi_value.size > 0` (checked above),
|
||||
// pointing to a valid C-allocated buffer of at least `size` bytes.
|
||||
unsafe { std::slice::from_raw_parts(ffi_value.data, ffi_value.size).to_vec() }
|
||||
};
|
||||
// SAFETY: `ffi_value` is a local variable, so the raw pointer is valid for this call.
|
||||
unsafe { ffi::free_bytes(&raw mut ffi_value) };
|
||||
Self::from(bytes::Bytes::from(vec))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
use crate::ffi;
|
||||
use crate::native::Error;
|
||||
use std::ffi::CString;
|
||||
|
||||
/// Input for witness generators
|
||||
pub struct WitnessInput<'dat> {
|
||||
/// The circuit's dat file contents.
|
||||
dat: &'dat [u8],
|
||||
/// The JSON string containing the circuit inputs.
|
||||
inputs_json: CString,
|
||||
}
|
||||
|
||||
impl<'dat> WitnessInput<'dat> {
|
||||
pub fn new(dat: &'dat [u8], inputs_json: String) -> Result<Self, Error> {
|
||||
let inputs_json = CString::new(inputs_json).map_err(|error| {
|
||||
Error::InvalidInput(Some(format!(
|
||||
"The parameter inputs_json could not be converted to C string: {error}"
|
||||
)))
|
||||
})?;
|
||||
Ok(Self { dat, inputs_json })
|
||||
}
|
||||
|
||||
/// Borrows this value as a temporary FFI-compatible view.
|
||||
#[must_use]
|
||||
pub fn as_ffi(&'_ self) -> WitnessInputFfiGuard<'_> {
|
||||
WitnessInputFfiGuard::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Temporary FFI view of a [`WitnessInput`], which makes [`ffi::WitnessInput`] lifetime-aware.
|
||||
pub struct WitnessInputFfiGuard<'dat> {
|
||||
ffi: ffi::WitnessInput,
|
||||
_lifetime: std::marker::PhantomData<&'dat WitnessInput<'dat>>,
|
||||
}
|
||||
|
||||
impl<'dat> WitnessInputFfiGuard<'dat> {
|
||||
fn new(inner: &'dat WitnessInput) -> Self {
|
||||
let dat = ffi::ConstBytes {
|
||||
data: inner.dat.as_ptr(),
|
||||
size: inner.dat.len(),
|
||||
};
|
||||
let inputs_json = inner.inputs_json.as_ptr();
|
||||
let ffi = ffi::WitnessInput { dat, inputs_json };
|
||||
Self {
|
||||
ffi,
|
||||
_lifetime: std::marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<ffi::WitnessInput> for WitnessInputFfiGuard<'_> {
|
||||
fn as_ref(&self) -> &ffi::WitnessInput {
|
||||
&self.ffi
|
||||
}
|
||||
}
|
||||
191
src/circom_adapter.cpp
Normal file
191
src/circom_adapter.cpp
Normal file
@ -0,0 +1,191 @@
|
||||
#include "circom_adapter.hpp"
|
||||
#include "circom_fwd.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
Circom_Circuit* loadCircuit(const ConstBytes& circuit_bytes) {
|
||||
Circom_Circuit* circuit = new Circom_Circuit;
|
||||
|
||||
circuit->InputHashMap = new HashSignalInfo[get_size_of_input_hashmap()];
|
||||
uint dsize = get_size_of_input_hashmap() * sizeof(HashSignalInfo);
|
||||
memcpy((void*)(circuit->InputHashMap), (void*)circuit_bytes.data, dsize);
|
||||
|
||||
circuit->witness2SignalList = new u64[get_size_of_witness()];
|
||||
uint inisize = dsize;
|
||||
dsize = get_size_of_witness() * sizeof(u64);
|
||||
memcpy((void*)(circuit->witness2SignalList), (void*)(circuit_bytes.data + inisize), dsize);
|
||||
|
||||
circuit->circuitConstants = new FrElement[get_size_of_constants()];
|
||||
if (get_size_of_constants() > 0) {
|
||||
inisize += dsize;
|
||||
dsize = get_size_of_constants() * sizeof(FrElement);
|
||||
memcpy((void*)(circuit->circuitConstants), (void*)(circuit_bytes.data + inisize), dsize);
|
||||
}
|
||||
|
||||
std::map<u32, IOFieldDefPair> templateInsId2IOSignalInfo1;
|
||||
IOFieldDefPair* busInsId2FieldInfo1 = nullptr;
|
||||
if (get_size_of_io_map() > 0) {
|
||||
u32 index[get_size_of_io_map()];
|
||||
inisize += dsize;
|
||||
dsize = get_size_of_io_map() * sizeof(u32);
|
||||
memcpy((void*)index, (void*)(circuit_bytes.data + inisize), dsize);
|
||||
inisize += dsize;
|
||||
assert(inisize % sizeof(u32) == 0);
|
||||
assert(circuit_bytes.size % sizeof(u32) == 0);
|
||||
u32 dataiomap[(circuit_bytes.size - inisize) / sizeof(u32)];
|
||||
memcpy((void*)dataiomap, (void*)(circuit_bytes.data + inisize), circuit_bytes.size - inisize);
|
||||
u32* pu32 = dataiomap;
|
||||
for (int i = 0; i < get_size_of_io_map(); i++) {
|
||||
u32 n = *pu32;
|
||||
IOFieldDefPair p;
|
||||
p.len = n;
|
||||
IOFieldDef defs[n];
|
||||
pu32 += 1;
|
||||
for (u32 j = 0; j < n; j++) {
|
||||
defs[j].offset = *pu32;
|
||||
u32 len = *(pu32 + 1);
|
||||
defs[j].len = len;
|
||||
defs[j].lengths = new u32[len];
|
||||
memcpy((void*)defs[j].lengths, (void*)(pu32 + 2), len * sizeof(u32));
|
||||
pu32 += len + 2;
|
||||
defs[j].size = *pu32;
|
||||
defs[j].busId = *(pu32 + 1);
|
||||
pu32 += 2;
|
||||
}
|
||||
p.defs = (IOFieldDef*)calloc(p.len, sizeof(IOFieldDef));
|
||||
for (u32 j = 0; j < p.len; j++) {
|
||||
p.defs[j] = defs[j];
|
||||
}
|
||||
templateInsId2IOSignalInfo1[index[i]] = p;
|
||||
}
|
||||
busInsId2FieldInfo1 = (IOFieldDefPair*)calloc(get_size_of_bus_field_map(), sizeof(IOFieldDefPair));
|
||||
for (int i = 0; i < get_size_of_bus_field_map(); i++) {
|
||||
u32 n = *pu32;
|
||||
IOFieldDefPair p;
|
||||
p.len = n;
|
||||
IOFieldDef defs[n];
|
||||
pu32 += 1;
|
||||
for (u32 j = 0; j < n; j++) {
|
||||
defs[j].offset = *pu32;
|
||||
u32 len = *(pu32 + 1);
|
||||
defs[j].len = len;
|
||||
defs[j].lengths = new u32[len];
|
||||
memcpy((void*)defs[j].lengths, (void*)(pu32 + 2), len * sizeof(u32));
|
||||
pu32 += len + 2;
|
||||
defs[j].size = *pu32;
|
||||
defs[j].busId = *(pu32 + 1);
|
||||
pu32 += 2;
|
||||
}
|
||||
p.defs = (IOFieldDef*)calloc(10, sizeof(IOFieldDef));
|
||||
for (u32 j = 0; j < p.len; j++) {
|
||||
p.defs[j] = defs[j];
|
||||
}
|
||||
busInsId2FieldInfo1[i] = p;
|
||||
}
|
||||
}
|
||||
circuit->templateInsId2IOSignalInfo = move(templateInsId2IOSignalInfo1);
|
||||
circuit->busInsId2FieldInfo = busInsId2FieldInfo1;
|
||||
|
||||
return circuit;
|
||||
}
|
||||
|
||||
void loadJson(Circom_CalcWit *ctx, const char* inputs_json) {
|
||||
json jin = json::parse(inputs_json);
|
||||
json j;
|
||||
|
||||
//std::cout << jin << std::endl;
|
||||
std::string prefix = "";
|
||||
qualify_input(prefix, jin, j);
|
||||
//std::cout << j << std::endl;
|
||||
|
||||
u64 nItems = j.size();
|
||||
// printf("Items : %llu\n",nItems);
|
||||
if (nItems == 0){
|
||||
ctx->tryRunCircuit();
|
||||
}
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it) {
|
||||
// std::cout << it.key() << " => " << it.value() << '\n';
|
||||
u64 h = fnv1a(it.key());
|
||||
std::vector<FrElement> v;
|
||||
json2FrElements(it.value(),v);
|
||||
uint signalSize = ctx->getInputSignalSize(h);
|
||||
if (v.size() < signalSize) {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Error loading signal " << it.key() << ": Not enough values\n";
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
if (v.size() > signalSize) {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Error loading signal " << it.key() << ": Too many values\n";
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
for (uint i = 0; i<v.size(); i++){
|
||||
try {
|
||||
// std::cout << it.key() << "," << i << " => " << Fr_element2str(&(v[i])) << '\n';
|
||||
ctx->setInputSignal(h,i,v[i]);
|
||||
} catch (std::runtime_error e) {
|
||||
std::ostringstream errStrStream;
|
||||
errStrStream << "Error setting signal: " << it.key() << "\n" << e.what();
|
||||
throw std::runtime_error(errStrStream.str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeBinWitness(Circom_CalcWit *ctx, Bytes* output_witness) {
|
||||
std::vector<uint8_t> buf;
|
||||
|
||||
auto write = [&](const void* data, size_t size) {
|
||||
const uint8_t* p = (const uint8_t*)data;
|
||||
buf.insert(buf.end(), p, p + size);
|
||||
};
|
||||
|
||||
write("wtns", 4);
|
||||
|
||||
u32 version = 2;
|
||||
write(&version, 4);
|
||||
|
||||
u32 nSections = 2;
|
||||
write(&nSections, 4);
|
||||
|
||||
// Header
|
||||
u32 idSection1 = 1;
|
||||
write(&idSection1, 4);
|
||||
|
||||
u32 n8 = Fr_N64*8;
|
||||
|
||||
u64 idSection1length = 8 + n8;
|
||||
write(&idSection1length, 8);
|
||||
|
||||
write(&n8, 4);
|
||||
|
||||
write(Fr_q.longVal, Fr_N64*8);
|
||||
|
||||
uint Nwtns = get_size_of_witness();
|
||||
|
||||
u32 nVars = (u32)Nwtns;
|
||||
write(&nVars, 4);
|
||||
|
||||
// Data
|
||||
u32 idSection2 = 2;
|
||||
write(&idSection2, 4);
|
||||
|
||||
u64 idSection2length = (u64)n8*(u64)Nwtns;
|
||||
write(&idSection2length, 8);
|
||||
|
||||
FrElement v;
|
||||
|
||||
for (int i=0;i<Nwtns;i++) {
|
||||
ctx->getWitness(i, &v);
|
||||
Fr_toLongNormal(&v, &v);
|
||||
write(v.longVal, Fr_N64*8);
|
||||
}
|
||||
|
||||
size_t size = buf.size();
|
||||
output_witness->data = static_cast<uint8_t*>(malloc(size));
|
||||
if (output_witness->data == nullptr) return;
|
||||
output_witness->size = size;
|
||||
memcpy(output_witness->data, buf.data(), size);
|
||||
}
|
||||
13
src/circom_adapter.hpp
Normal file
13
src/circom_adapter.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef CIRCOM_ADAPTER_HPP
|
||||
#define CIRCOM_ADAPTER_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
#include "calcwit.hpp"
|
||||
#include "circom.hpp"
|
||||
|
||||
// Return value
|
||||
Circom_Circuit* loadCircuit(const ConstBytes& circuit);
|
||||
void loadJson(Circom_CalcWit *ctx, const char* inputs_json);
|
||||
void writeBinWitness(Circom_CalcWit *ctx, Bytes* output_witness);
|
||||
|
||||
#endif
|
||||
30
src/circom_fwd.hpp
Normal file
30
src/circom_fwd.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef CIRCOM_FWD_HPP
|
||||
#define CIRCOM_FWD_HPP
|
||||
|
||||
/// Forward declarations for symbols defined in circom-generated main.cpp.
|
||||
///
|
||||
/// Circom compiles each circuit into a self-contained main.cpp that defines the witness generation
|
||||
/// logic alongside several helper functions.
|
||||
/// This header exposes those symbols so that FFI code can call into them without pulling in the full circom source.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "calcwit.hpp"
|
||||
#include "circom.hpp"
|
||||
#include "fr.hpp"
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
/// Forward declaration of circom main(). Renamed via -Dmain=circom_main to avoid UB.
|
||||
/// TODO: Successful path has no explicit return.
|
||||
int circom_main(int argc, char* argv[]);
|
||||
bool check_valid_number(std::string& s, uint base);
|
||||
void json2FrElements(json val, std::vector<FrElement>& vval);
|
||||
json::value_t check_type(std::string prefix, json in);
|
||||
void qualify_input(std::string prefix, json& in, json& in1);
|
||||
void qualify_input_list(std::string prefix, json& in, json& in1);
|
||||
|
||||
#endif
|
||||
119
src/poc/ffi.cpp
Normal file
119
src/poc/ffi.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "poc/ffi.hpp"
|
||||
#include "circom_fwd.hpp"
|
||||
#include "circom_adapter.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
template<typename T>
|
||||
static Status exceptions_into_status(T&& func) {
|
||||
try {
|
||||
return func();
|
||||
} catch (const std::bad_alloc&) {
|
||||
return status_from_code(StatusCode_OutOfMemory);
|
||||
} catch (const std::exception& e) {
|
||||
return status_new(StatusCode_DynError, e.what());
|
||||
} catch (...) {
|
||||
return status_new(StatusCode_DynError, "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
static Status validate_generate_witness_from_files_arguments(const char* dat, const char* inputs, const char* output) {
|
||||
if (dat == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "dat is null.");
|
||||
}
|
||||
if (inputs == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "inputs is null.");
|
||||
}
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_from_files_impl(const char* dat, const char* inputs, const char* output) {
|
||||
char* argv[] = {
|
||||
const_cast<char*>(dat),
|
||||
const_cast<char*>(inputs),
|
||||
const_cast<char*>(output),
|
||||
nullptr
|
||||
};
|
||||
|
||||
const int code = circom_main(3, argv);
|
||||
if (code == 0) {
|
||||
return status_ok();
|
||||
}
|
||||
const std::string message = "Witness generation [circom main()] failed with code: " + std::to_string(code) + ".";
|
||||
return status_new(StatusCode_DynError, message.c_str());
|
||||
}
|
||||
|
||||
extern "C" Status poc_generate_witness_from_files(const char* dat, const char* inputs, const char* output) {
|
||||
const Status status = validate_generate_witness_from_files_arguments(dat, inputs, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_from_files_impl(dat, inputs, output);
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Memory-based entry point ----
|
||||
|
||||
static Status validate_witness_arguments(const WitnessInput* input, const Bytes* output) {
|
||||
if (input == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input is null.");
|
||||
}
|
||||
if (input->dat.data == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.data is null.");
|
||||
}
|
||||
if (input->dat.size == 0) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.size is zero.");
|
||||
}
|
||||
if (input->inputs_json == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.inputs_json is null.");
|
||||
}
|
||||
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
if (output->data != nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output.data is not null.");
|
||||
}
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
loadJson(ctx, input->inputs_json);
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
extern "C" Status poc_generate_witness(const WitnessInput* input, Bytes* output) {
|
||||
const Status status = validate_witness_arguments(input, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_impl(input, output);
|
||||
});
|
||||
}
|
||||
42
src/poc/ffi.hpp
Normal file
42
src/poc/ffi.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef FFI_POC_HPP
|
||||
#define FFI_POC_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Generates a witness by delegating to the circom-generated CLI entry point.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `dat`: Path to the .dat file. Must be extensionless.
|
||||
/// - `inputs`: Path to the inputs file for the circuit. Must be a JSON file.
|
||||
/// - `output`: Path to the output file where the witness will be written.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and writes the witness to the specified output file.
|
||||
/// On failure, returns a `Status` with an appropriate error code.
|
||||
Status poc_generate_witness_from_files(const char* dat, const char* inputs, const char* output);
|
||||
|
||||
/// Generates a witness from in-memory buffers.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `input`: The `WitnessInput` struct containing the circuit information.
|
||||
/// - `output`: Pointer to a `Bytes` struct that will be populated with the generated witness bytes.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and populates `output` with the generated witness bytes. The
|
||||
/// caller is responsible for freeing the resources allocated into `output` by this function using `free_bytes`.
|
||||
/// On failure, returns a `Status` with an appropriate error code, and `output` will not be modified.
|
||||
Status poc_generate_witness(const WitnessInput* input, Bytes* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
119
src/pol/ffi.cpp
Normal file
119
src/pol/ffi.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "pol/ffi.hpp"
|
||||
#include "circom_fwd.hpp"
|
||||
#include "circom_adapter.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
template<typename T>
|
||||
static Status exceptions_into_status(T&& func) {
|
||||
try {
|
||||
return func();
|
||||
} catch (const std::bad_alloc&) {
|
||||
return status_from_code(StatusCode_OutOfMemory);
|
||||
} catch (const std::exception& e) {
|
||||
return status_new(StatusCode_DynError, e.what());
|
||||
} catch (...) {
|
||||
return status_new(StatusCode_DynError, "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
static Status validate_generate_witness_from_files_arguments(const char* dat, const char* inputs, const char* output) {
|
||||
if (dat == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "dat is null.");
|
||||
}
|
||||
if (inputs == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "inputs is null.");
|
||||
}
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_from_files_impl(const char* dat, const char* inputs, const char* output) {
|
||||
char* argv[] = {
|
||||
const_cast<char*>(dat),
|
||||
const_cast<char*>(inputs),
|
||||
const_cast<char*>(output),
|
||||
nullptr
|
||||
};
|
||||
|
||||
const int code = circom_main(3, argv);
|
||||
if (code == 0) {
|
||||
return status_ok();
|
||||
}
|
||||
const std::string message = "Witness generation [circom main()] failed with code: " + std::to_string(code) + ".";
|
||||
return status_new(StatusCode_DynError, message.c_str());
|
||||
}
|
||||
|
||||
extern "C" Status pol_generate_witness_from_files(const char* dat, const char* inputs, const char* output) {
|
||||
const Status status = validate_generate_witness_from_files_arguments(dat, inputs, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_from_files_impl(dat, inputs, output);
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Memory-based entry point ----
|
||||
|
||||
static Status validate_witness_arguments(const WitnessInput* input, const Bytes* output) {
|
||||
if (input == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input is null.");
|
||||
}
|
||||
if (input->dat.data == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.data is null.");
|
||||
}
|
||||
if (input->dat.size == 0) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.size is zero.");
|
||||
}
|
||||
if (input->inputs_json == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.inputs_json is null.");
|
||||
}
|
||||
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
if (output->data != nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output.data is not null.");
|
||||
}
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
loadJson(ctx, input->inputs_json);
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
extern "C" Status pol_generate_witness(const WitnessInput* input, Bytes* output) {
|
||||
const Status status = validate_witness_arguments(input, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_impl(input, output);
|
||||
});
|
||||
}
|
||||
42
src/pol/ffi.hpp
Normal file
42
src/pol/ffi.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef FFI_POL_HPP
|
||||
#define FFI_POL_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Generates a witness by delegating to the circom-generated CLI entry point.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `dat`: Path to the .dat file. Must be extensionless.
|
||||
/// - `inputs`: Path to the inputs file for the circuit. Must be a JSON file.
|
||||
/// - `output`: Path to the output file where the witness will be written.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and writes the witness to the specified output file.
|
||||
/// On failure, returns a `Status` with an appropriate error code.
|
||||
Status pol_generate_witness_from_files(const char* dat, const char* inputs, const char* output);
|
||||
|
||||
/// Generates a witness from in-memory buffers.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `input`: The `WitnessInput` struct containing the circuit information.
|
||||
/// - `output`: Pointer to a `Bytes` struct that will be populated with the generated witness bytes.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and populates `output` with the generated witness bytes. The
|
||||
/// caller is responsible for freeing the resources allocated into `output` by this function using `free_bytes`.
|
||||
/// On failure, returns a `Status` with an appropriate error code, and `output` will not be modified.
|
||||
Status pol_generate_witness(const WitnessInput* input, Bytes* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
119
src/poq/ffi.cpp
Normal file
119
src/poq/ffi.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "poq/ffi.hpp"
|
||||
#include "circom_fwd.hpp"
|
||||
#include "circom_adapter.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
template<typename T>
|
||||
static Status exceptions_into_status(T&& func) {
|
||||
try {
|
||||
return func();
|
||||
} catch (const std::bad_alloc&) {
|
||||
return status_from_code(StatusCode_OutOfMemory);
|
||||
} catch (const std::exception& e) {
|
||||
return status_new(StatusCode_DynError, e.what());
|
||||
} catch (...) {
|
||||
return status_new(StatusCode_DynError, "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
static Status validate_generate_witness_from_files_arguments(const char* dat, const char* inputs, const char* output) {
|
||||
if (dat == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "dat is null.");
|
||||
}
|
||||
if (inputs == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "inputs is null.");
|
||||
}
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_from_files_impl(const char* dat, const char* inputs, const char* output) {
|
||||
char* argv[] = {
|
||||
const_cast<char*>(dat),
|
||||
const_cast<char*>(inputs),
|
||||
const_cast<char*>(output),
|
||||
nullptr
|
||||
};
|
||||
|
||||
const int code = circom_main(3, argv);
|
||||
if (code == 0) {
|
||||
return status_ok();
|
||||
}
|
||||
const std::string message = "Witness generation [circom main()] failed with code: " + std::to_string(code) + ".";
|
||||
return status_new(StatusCode_DynError, message.c_str());
|
||||
}
|
||||
|
||||
extern "C" Status poq_generate_witness_from_files(const char* dat, const char* inputs, const char* output) {
|
||||
const Status status = validate_generate_witness_from_files_arguments(dat, inputs, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_from_files_impl(dat, inputs, output);
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Memory-based entry point ----
|
||||
|
||||
static Status validate_witness_arguments(const WitnessInput* input, const Bytes* output) {
|
||||
if (input == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input is null.");
|
||||
}
|
||||
if (input->dat.data == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.data is null.");
|
||||
}
|
||||
if (input->dat.size == 0) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.size is zero.");
|
||||
}
|
||||
if (input->inputs_json == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.inputs_json is null.");
|
||||
}
|
||||
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
if (output->data != nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output.data is not null.");
|
||||
}
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
loadJson(ctx, input->inputs_json);
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
extern "C" Status poq_generate_witness(const WitnessInput* input, Bytes* output) {
|
||||
const Status status = validate_witness_arguments(input, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_impl(input, output);
|
||||
});
|
||||
}
|
||||
42
src/poq/ffi.hpp
Normal file
42
src/poq/ffi.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef FFI_POQ_HPP
|
||||
#define FFI_POQ_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Generates a witness by delegating to the circom-generated CLI entry point.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `dat`: Path to the .dat file. Must be extensionless.
|
||||
/// - `inputs`: Path to the inputs file for the circuit. Must be a JSON file.
|
||||
/// - `output`: Path to the output file where the witness will be written.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and writes the witness to the specified output file.
|
||||
/// On failure, returns a `Status` with an appropriate error code.
|
||||
Status poq_generate_witness_from_files(const char* dat, const char* inputs, const char* output);
|
||||
|
||||
/// Generates a witness from in-memory buffers.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `input`: The `WitnessInput` struct containing the circuit information.
|
||||
/// - `output`: Pointer to a `Bytes` struct that will be populated with the generated witness bytes.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and populates `output` with the generated witness bytes. The
|
||||
/// caller is responsible for freeing the resources allocated into `output` by this function using `free_bytes`.
|
||||
/// On failure, returns a `Status` with an appropriate error code, and `output` will not be modified.
|
||||
Status poq_generate_witness(const WitnessInput* input, Bytes* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
119
src/signature/ffi.cpp
Normal file
119
src/signature/ffi.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
#include "signature/ffi.hpp"
|
||||
#include "circom_fwd.hpp"
|
||||
#include "circom_adapter.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../types.hpp"
|
||||
|
||||
template<typename T>
|
||||
static Status exceptions_into_status(T&& func) {
|
||||
try {
|
||||
return func();
|
||||
} catch (const std::bad_alloc&) {
|
||||
return status_from_code(StatusCode_OutOfMemory);
|
||||
} catch (const std::exception& e) {
|
||||
return status_new(StatusCode_DynError, e.what());
|
||||
} catch (...) {
|
||||
return status_new(StatusCode_DynError, "An unknown error occurred.");
|
||||
}
|
||||
}
|
||||
|
||||
static Status validate_generate_witness_from_files_arguments(const char* dat, const char* inputs, const char* output) {
|
||||
if (dat == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "dat is null.");
|
||||
}
|
||||
if (inputs == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "inputs is null.");
|
||||
}
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_from_files_impl(const char* dat, const char* inputs, const char* output) {
|
||||
char* argv[] = {
|
||||
const_cast<char*>(dat),
|
||||
const_cast<char*>(inputs),
|
||||
const_cast<char*>(output),
|
||||
nullptr
|
||||
};
|
||||
|
||||
const int code = circom_main(3, argv);
|
||||
if (code == 0) {
|
||||
return status_ok();
|
||||
}
|
||||
const std::string message = "Witness generation [circom main()] failed with code: " + std::to_string(code) + ".";
|
||||
return status_new(StatusCode_DynError, message.c_str());
|
||||
}
|
||||
|
||||
extern "C" Status signature_generate_witness_from_files(const char* dat, const char* inputs, const char* output) {
|
||||
const Status status = validate_generate_witness_from_files_arguments(dat, inputs, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_from_files_impl(dat, inputs, output);
|
||||
});
|
||||
}
|
||||
|
||||
// ---- Memory-based entry point ----
|
||||
|
||||
static Status validate_witness_arguments(const WitnessInput* input, const Bytes* output) {
|
||||
if (input == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input is null.");
|
||||
}
|
||||
if (input->dat.data == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.data is null.");
|
||||
}
|
||||
if (input->dat.size == 0) {
|
||||
return status_new(StatusCode_InvalidInput, "input.dat.size is zero.");
|
||||
}
|
||||
if (input->inputs_json == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "input.inputs_json is null.");
|
||||
}
|
||||
|
||||
if (output == nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output is null.");
|
||||
}
|
||||
if (output->data != nullptr) {
|
||||
return status_new(StatusCode_InvalidInput, "output.data is not null.");
|
||||
}
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
static Status generate_witness_impl(const WitnessInput* input, Bytes* output) {
|
||||
const ConstBytes& circuit_bytes = input->dat;
|
||||
|
||||
Circom_Circuit* circuit = loadCircuit(circuit_bytes);
|
||||
Circom_CalcWit* ctx = new Circom_CalcWit(circuit);
|
||||
|
||||
loadJson(ctx, input->inputs_json);
|
||||
if (ctx->getRemaingInputsToBeSet()!=0) {
|
||||
const std::string message = "Not all inputs have been set. Only " + std::to_string(get_main_input_signal_no()-ctx->getRemaingInputsToBeSet()) + " out of " + std::to_string(get_main_input_signal_no()) + ".";
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
return status_new(StatusCode_InvalidInput, message.c_str());
|
||||
}
|
||||
|
||||
writeBinWitness(ctx, output);
|
||||
delete ctx;
|
||||
delete circuit;
|
||||
|
||||
return status_ok();
|
||||
}
|
||||
|
||||
extern "C" Status signature_generate_witness(const WitnessInput* input, Bytes* output) {
|
||||
const Status status = validate_witness_arguments(input, output); // NOLINT: if-init
|
||||
if (status_is_error(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return exceptions_into_status([&] {
|
||||
return generate_witness_impl(input, output);
|
||||
});
|
||||
}
|
||||
42
src/signature/ffi.hpp
Normal file
42
src/signature/ffi.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
#ifndef FFI_SIGNATURE_HPP
|
||||
#define FFI_SIGNATURE_HPP
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Generates a witness by delegating to the circom-generated CLI entry point.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `dat`: Path to the .dat file. Must be extensionless.
|
||||
/// - `inputs`: Path to the inputs file for the circuit. Must be a JSON file.
|
||||
/// - `output`: Path to the output file where the witness will be written.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and writes the witness to the specified output file.
|
||||
/// On failure, returns a `Status` with an appropriate error code.
|
||||
Status signature_generate_witness_from_files(const char* dat, const char* inputs, const char* output);
|
||||
|
||||
/// Generates a witness from in-memory buffers.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - `input`: The `WitnessInput` struct containing the circuit information.
|
||||
/// - `output`: Pointer to a `Bytes` struct that will be populated with the generated witness bytes.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// On success, returns a `Status` with `StatusCode_Ok` and populates `output` with the generated witness bytes. The
|
||||
/// caller is responsible for freeing the resources allocated into `output` by this function using `free_bytes`.
|
||||
/// On failure, returns a `Status` with an appropriate error code, and `output` will not be modified.
|
||||
Status signature_generate_witness(const WitnessInput* input, Bytes* output);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
92
src/types.hpp
Normal file
92
src/types.hpp
Normal file
@ -0,0 +1,92 @@
|
||||
#ifndef TYPES_HPP
|
||||
#define TYPES_HPP
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define STATUS_MESSAGE_LENGTH 256
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Mutable byte buffer.
|
||||
typedef struct Bytes {
|
||||
uint8_t* data;
|
||||
size_t size;
|
||||
} Bytes;
|
||||
|
||||
/// Immutable byte buffer.
|
||||
typedef struct ConstBytes {
|
||||
const uint8_t* data;
|
||||
size_t size;
|
||||
} ConstBytes;
|
||||
|
||||
typedef enum StatusCode {
|
||||
StatusCode_Ok = 0,
|
||||
StatusCode_DynError = 1,
|
||||
StatusCode_InvalidInput = 2,
|
||||
StatusCode_OutOfMemory = 3,
|
||||
} StatusCode;
|
||||
|
||||
static inline bool status_code_is_ok(const StatusCode code) {
|
||||
return code == StatusCode_Ok;
|
||||
}
|
||||
|
||||
static inline bool status_code_is_error(const StatusCode code) {
|
||||
return !status_code_is_ok(code);
|
||||
}
|
||||
|
||||
/// A status code with an optional human-readable description.
|
||||
typedef struct Status {
|
||||
StatusCode code;
|
||||
char message[STATUS_MESSAGE_LENGTH];
|
||||
} Status;
|
||||
|
||||
static inline Status status_new(const StatusCode code, const char* message) {
|
||||
Status status = {code, {}};
|
||||
if (message != NULL) {
|
||||
strncpy(status.message, message, STATUS_MESSAGE_LENGTH - 1);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
static inline Status status_from_code(const StatusCode code) {
|
||||
return status_new(code, NULL);
|
||||
}
|
||||
static inline Status status_ok() {
|
||||
return status_from_code(StatusCode_Ok);
|
||||
}
|
||||
|
||||
static inline bool status_is_ok(const Status status) {
|
||||
return status_code_is_ok(status.code);
|
||||
}
|
||||
static inline bool status_is_error(const Status status) {
|
||||
return status_code_is_error(status.code);
|
||||
}
|
||||
|
||||
/// Inputs for witness generation.
|
||||
typedef struct WitnessInput {
|
||||
/// Contents of the circuit's .dat file.
|
||||
const ConstBytes dat;
|
||||
/// Null-terminated JSON string of circuit inputs.
|
||||
const char* inputs_json;
|
||||
} WitnessInput;
|
||||
|
||||
/// Static inline is inlined at every call site and cannot be linked, so each language binding must reimplement it.
|
||||
/// This is the best-effort approach for now.
|
||||
/// TODO: Make this an exported symbol so Rust (and other callers) can link against a single canonical definition.
|
||||
static inline void free_bytes(Bytes* bytes) {
|
||||
if (bytes == NULL)
|
||||
return;
|
||||
free(bytes->data);
|
||||
bytes->data = NULL;
|
||||
bytes->size = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TYPES_HPP
|
||||
Loading…
x
Reference in New Issue
Block a user