Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(verifier): Add Circom verifier to Aligned #673

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions operator/circom/circom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package circom

Check failure on line 1 in operator/circom/circom.go

View workflow job for this annotation

GitHub Actions / lint

: # github.com/yetanotherco/aligned_layer/operator/circom

/*
#cgo linux LDFLAGS: ${SRCDIR}/lib/libcircom_verifier.a -ldl -lrt -lm -lssl -lcrypto -Wl,--allow-multiple-definition
#cgo darwin LDFLAGS: -L./lib -lcircom_verifier

#include "lib/circom.h"

Check failure on line 7 in operator/circom/circom.go

View workflow job for this annotation

GitHub Actions / lint

fatal error: lib/circom.h: No such file or directory

Check failure on line 7 in operator/circom/circom.go

View workflow job for this annotation

GitHub Actions / lint

fatal error: lib/circom.h: No such file or directory
*/
import "C"
import "unsafe"

// MaxProofSize 4KB
const MaxProofSize = 8 * 1024

// MaxProofSize 4KB
const MaxParamsSize = 8 * 1024

// MaxConstraintSystemSize 2KB
const MaxConstraintSystemSize = 2 * 1024

// MaxVerificationKeySize 1KB
const MaxVerifierKeySize = 1024

// MaxPublicInputSize 4KB
const MaxPublicInputSize = 4 * 1024

// Merge all pointers into one array and send across interface
func VerifyCircomProof(
proofBuffer [MaxProofSize]byte, proofLen_u32 uint32,
vkBuffer [MaxVerifierKeySize]byte, vkLen_u32 uint32,
publicInputBuffer [MaxPublicInputSize]byte, publicInputLen_u32 uint32,
) bool {
// Cast data pointers to C-types
proofPtr := (*C.uchar)(unsafe.Pointer(&proofBuffer[0]))
vkPtr := (*C.uchar)(unsafe.Pointer(&vkBuffer[0]))
publicInputPtr := (*C.uchar)(unsafe.Pointer(&publicInputBuffer[0]))

// Cast data length to C-types
proofLen := (C.uint32_t)(proofLen_u32)
vkLen := (C.uint32_t)(vkLen_u32)
publicInputLen := (C.uint32_t)(publicInputLen_u32)

return (bool)(C.verify_circom_proof_ffi(
proofPtr, proofLen,
vkPtr, vkLen,
publicInputPtr, publicInputLen),
)
}
29 changes: 29 additions & 0 deletions operator/circom/circom_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package circom_test

import (
"os"
"testing"

"github.com/yetanotherco/aligned_layer/operator/circom"

Check failure on line 7 in operator/circom/circom_test.go

View workflow job for this annotation

GitHub Actions / lint

could not import github.com/yetanotherco/aligned_layer/operator/circom (-: # github.com/yetanotherco/aligned_layer/operator/circom
)

func TestCircomProofVerifies(t *testing.T) {
proofBytes, err := os.ReadFile("../../scripts/test_files/circom/proof")
if err != nil {
t.Errorf("could not open proof file: %s", err)
}

keyBytes, err := os.ReadFile("../../scripts/test_files/circom/key")
if err != nil {
t.Errorf("could not open image id file: %s", err)
}

publicInputBytes, err := os.ReadFile("../../scripts/test_files/circom/public_inputs")
if err != nil {
t.Errorf("could not open public input file: %s", err)
}

if !circom.VerifyCircomProof([8192]byte(proofBytes), uint32(len(proofBytes)), [1024]byte(keyBytes), uint32(len(keyBytes)), publicInputBytes, uint32(len(publicInputBytes))) {
t.Errorf("proof did not verify")
}
}
32 changes: 32 additions & 0 deletions operator/circom/src/circom.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <stdexcept>

#include "verifier.h"
extern "C" {
bool verify_circom_proof_ffi(unsigned char *proof, uint32_t proof_len,
unsigned char *key, uint32_t key_len,
unsigned char *public_inputs, uint32_t public_input_len) {

char errorMessage[256];

const int error = groth16_verify(proof.dataAsString().c_str(),
public_inputs.dataAsString().c_str(),
key.dataAsString().c_str(),
errorMessage, sizeof(errorMessage));

if (error == VERIFIER_VALID_PROOF) {

std::cerr << "Result: Valid proof" << std::endl;
return EXIT_SUCCESS;

} else if (error == VERIFIER_INVALID_PROOF) {

std::cerr << "Result: Invalid proof" << std::endl;
return EXIT_FAILURE;

} else {
std::cerr << "Error: " << errorMessage << '\n';
return EXIT_FAILURE;
}

}
}
6 changes: 6 additions & 0 deletions operator/circom/src/circom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <stdbool.h>
#include <stdint.h>

bool verify_circom_proof_ffi(unsigned char *proof_bytes, uint32_t proof_len,
unsigned char *verifier_params_bytes, uint32_t vk_len,
unsigned char *public_input_bytes, uint32_t public_input_len);
Binary file added scripts/test_files/circom/circuit_final.zkey
Binary file not shown.
94 changes: 94 additions & 0 deletions scripts/test_files/circom/verification_key.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{
"protocol": "groth16",
"curve": "bn128",
"nPublic": 1,
"vk_alpha_1": [
"20491192805390485299153009773594534940189261866228447918068658471970481763042",
"9383485363053290200918347156157836566562967994039712273449902621266178545958",
"1"
],
"vk_beta_2": [
[
"6375614351688725206403948262868962793625744043794305715222011528459656738731",
"4252822878758300859123897981450591353533073413197771768651442665752259397132"
],
[
"10505242626370262277552901082094356697409835680220590971873171140371331206856",
"21847035105528745403288232691147584728191162732299865338377159692350059136679"
],
[
"1",
"0"
]
],
"vk_gamma_2": [
[
"10857046999023057135944570762232829481370756359578518086990519993285655852781",
"11559732032986387107991004021392285783925812861821192530917403151452391805634"
],
[
"8495653923123431417604973247489272438418190587263600148770280649306958101930",
"4082367875863433681332203403145435568316851327593401208105741076214120093531"
],
[
"1",
"0"
]
],
"vk_delta_2": [
[
"10056322322891219854268402349413163241212310059164911282424429574909837055562",
"12530590306125500264744927194515711435185554567505632685219127544784956548143"
],
[
"3198185062701173616088252494763783302271691955806883740290181107756211891848",
"5935918403904311654026004102721758093545898651591152833499461744182771134433"
],
[
"1",
"0"
]
],
"vk_alphabeta_12": [
[
[
"2029413683389138792403550203267699914886160938906632433982220835551125967885",
"21072700047562757817161031222997517981543347628379360635925549008442030252106"
],
[
"5940354580057074848093997050200682056184807770593307860589430076672439820312",
"12156638873931618554171829126792193045421052652279363021382169897324752428276"
],
[
"7898200236362823042373859371574133993780991612861777490112507062703164551277",
"7074218545237549455313236346927434013100842096812539264420499035217050630853"
]
],
[
[
"7077479683546002997211712695946002074877511277312570035766170199895071832130",
"10093483419865920389913245021038182291233451549023025229112148274109565435465"
],
[
"4595479056700221319381530156280926371456704509942304414423590385166031118820",
"19831328484489333784475432780421641293929726139240675179672856274388269393268"
],
[
"11934129596455521040620786944827826205713621633706285934057045369193958244500",
"8037395052364110730298837004334506829870972346962140206007064471173334027475"
]
]
],
"IC": [
[
"11932556748928578545728995536027201108657542124050415478292462831771509095304",
"9149370873483970774321348444196634478850132879039205704924275954730380431457",
"1"
],
[
"17482596306642470706171849523416052476936601967698452358356767181693176975875",
"16875289648181723199466955981261105815550134487513330320459939834929279218791",
"1"
]
]
}
Binary file added scripts/test_files/circom/witness.wtns
Binary file not shown.
Loading