innitial commit

This commit is contained in:
Dmitriy Ryajov 2024-01-19 14:29:03 -06:00
parent 45d0aaacb5
commit 35253db96b
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4
10 changed files with 203 additions and 0 deletions

6
.gitignore vendored
View File

@ -1,3 +1,9 @@
nimcache/ nimcache/
nimblecache/ nimblecache/
htmldocs/ htmldocs/
*
!*/
!*.*
*.exe
.DS_Store

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "vendor/circom-compat-ffi"]
path = vendor/circom-compat-ffi
url = https://github.com/codex-storage/circom-compat-ffi.git

8
build.nims Normal file
View File

@ -0,0 +1,8 @@
import std/os
task genffi, "update the nim ffi bindings":
exec "cargo install --git https://github.com/arnetheduck/nbindgen#e80a85f1505d78eeae78ce33b6f406603be27d35 nbindgen"
exec "nbindgen -c ./cbindgen.toml vendor/circom-compat-ffi --output circomcompatffi.nim"
task tests, "run unit tests":
exec "nim c -r tests/testcircomcompat.nim"

32
cbindgen.toml Normal file
View File

@ -0,0 +1,32 @@
[parse]
parse_deps = false
expand = ["circom-compat-ffi"]
# Configuration for name mangling
[export.mangle]
# Whether the types should be renamed during mangling, for example
# c_char -> CChar, etc.
rename_types = "CamelCase"
# Whether the underscores from the mangled name should be omitted.
remove_underscores = true
[struct]
# A rule to use to rename struct field names. The renaming assumes the input is
# the Rust standard snake_case, however it acccepts all the different rename_args
# inputs. This means many options here are no-ops or redundant.
#
# possible values (that actually do something):
# * "CamelCase": my_arg => myArg
# * "PascalCase": my_arg => MyArg
# * "GeckoCase": my_arg => mMyArg
# * "ScreamingSnakeCase": my_arg => MY_ARG
# * "None": apply no renaming
#
# technically possible values (that shouldn't have a purpose here):
# * "SnakeCase": apply no renaming
# * "LowerCase": apply no renaming (actually applies to_lowercase, is this bug?)
# * "UpperCase": same as ScreamingSnakeCase in this context
# * "QualifiedScreamingSnakeCase" => same as ScreamingSnakeCase in this context
#
# default: "None"
rename_fields = "CamelCase"

22
circomcompat.nim Normal file
View File

@ -0,0 +1,22 @@
import std/os
import std/strutils
import std/macros
const
currentDir = currentSourcePath().parentDir()
libDir* = currentDir/"vendor/circom-compat-ffi/target"/"release"
libPath* = libDir/"libcircom_compat_ffi.a"
static:
let cmd = "cd vendor/circom-compat-ffi && cargo build --release"
warning "\nBuilding circom compat ffi: " & cmd
let (output, exitCode) = gorgeEx cmd
for ln in output.splitLines():
warning("cargo> " & ln)
if exitCode != 0:
raiseAssert("Failed to build circom-compat-ffi")
{.passl: "-lcircom_compat_ffi" & " -L" & libDir.}
include circomcompatffi

14
circomcompat.nimble Normal file
View File

@ -0,0 +1,14 @@
# Package
version = "0.1.0"
author = "Dmitriy Ryajov"
description = "Nim wrapper for rust circom compat (ark-circom)"
license = "MIT"
srcDir = "src"
# Dependencies
requires "nim >= 1.6.18"
include "build.nims"

84
circomcompatffi.nim Normal file
View File

@ -0,0 +1,84 @@
const ERR_UNKNOWN* = -1
const ERR_OK* = 0
const ERR_WASM_PATH* = 1
const ERR_R1CS_PATH* = 2
const ERR_ZKEY_PATH* = 3
const ERR_INPUT_NAME* = 4
const ERR_INVALID_INPUT* = 5
const ERR_CANT_READ_ZKEY* = 6
const ERR_CIRCOM_BUILDER* = 7
const ERR_FAILED_TO_DESERIALIZE_PROOF* = 8
const ERR_FAILED_TO_DESERIALIZE_INPUTS* = 9
type CircomCompatCtx* {.incompleteStruct.} = object
type Buffer* = object
data*: pointer
len*: uint
## # Safety
#
proc init_circom_compat*(r1cs_path: pointer,
wasm_path: pointer,
zkey_path: pointer,
ctx_ptr: ptr ptr CircomCompatCtx): int32 {.importc: "init_circom_compat".}
proc release_circom_compat*(ctx_ptr: ptr ptr CircomCompatCtx): void {.importc: "release_circom_compat".}
## # Safety
#
proc push_input_u256_array*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input_ptr: pointer,
len: uint): int32 {.importc: "push_input_u256_array".}
## # Safety
#
proc prove_circuit*(ctx_ptr: ptr CircomCompatCtx,
proof_bytes_ptr: ptr ptr Buffer,
inputs_bytes_ptr: ptr ptr Buffer): int32 {.importc: "prove_circuit".}
## # Safety
#
proc verify_circuit*(ctx_ptr: ptr CircomCompatCtx,
proof_bytes_ptr: ptr Buffer,
inputs_bytes_ptr: ptr Buffer): int32 {.importc: "verify_circuit".}
proc push_input_numeric_i8*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: int8): int32 {.importc: "push_input_numeric_i8".}
proc push_input_numeric_u8*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: uint8): int32 {.importc: "push_input_numeric_u8".}
proc push_input_numeric_i16*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: int16): int32 {.importc: "push_input_numeric_i16".}
proc push_input_numeric_u16*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: uint16): int32 {.importc: "push_input_numeric_u16".}
proc push_input_numeric_i32*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: int32): int32 {.importc: "push_input_numeric_i32".}
proc push_input_numeric_u32*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: uint32): int32 {.importc: "push_input_numeric_u32".}
proc push_input_numeric_u64*(ctx_ptr: ptr CircomCompatCtx,
name_ptr: pointer,
input: uint64): int32 {.importc: "push_input_numeric_u64".}

1
tests/config.nims Normal file
View File

@ -0,0 +1 @@
switch("path", "$projectDir/")

32
tests/testcircom.nim Normal file
View File

@ -0,0 +1,32 @@
import std/os
import std/unittest
import ../circomcompat
suite "Test circom compat nim":
test "Should generate witness, prove and verify":
let
r1csPath = "vendor/circom-compat-ffi/fixtures/mycircuit.r1cs".cstring
wasmPath = "vendor/circom-compat-ffi/fixtures/mycircuit.wasm".cstring
var ctx: ptr CircomCompatCtx
let res = init_circom_compat(
r1csPath,
wasmPath,
nil,
ctx.addr)
check ctx.push_input_numeric_i8("a".cstring, 3) == ERR_OK
check ctx.push_input_numeric_i8("b".cstring, 11) == ERR_OK
var proofBytes: ptr Buffer
var publicBytes: ptr Buffer
check ctx.prove_circuit(proofBytes.addr, publicBytes.addr) == ERR_OK
check proofBytes.len > 0
check publicBytes.len > 0
check ctx.verify_circuit(proofBytes, publicBytes) == ERR_OK
check res == ERR_OK

1
vendor/circom-compat-ffi vendored Submodule

@ -0,0 +1 @@
Subproject commit 5a522239a62262f6b0fefa1f1d54a22b72da5b38