From 515e4b250d3c03e715eae2a95dbf1c67af14f06d Mon Sep 17 00:00:00 2001 From: samdelaney Date: Wed, 18 Jun 2025 15:00:33 -0700 Subject: [PATCH 1/7] WIP - groth16 rewrite --- zkp/lib/groth/groth.ak | 240 ++++++++++------------------------------- 1 file changed, 59 insertions(+), 181 deletions(-) diff --git a/zkp/lib/groth/groth.ak b/zkp/lib/groth/groth.ak index 92936dc..a861320 100644 --- a/zkp/lib/groth/groth.ak +++ b/zkp/lib/groth/groth.ak @@ -1,24 +1,32 @@ -use aiken/builtin -use aiken/collection/list -use aiken/crypto/bls12_381/g1 -use aiken/crypto/bls12_381/g2 -use aiken/crypto/bls12_381/scalar -use common/common +pub type G1Point = + ByteArray + +pub type G2Point = + ByteArray + +pub type Field = + Int -// Groth16 specific types pub type GrothVerificationKey { n_public: Int, - vk_alpha_g1: common.G1Point, - vk_beta_g2: common.G2Point, - vk_gamma_g2: common.G2Point, - vk_delta_g2: common.G2Point, - vk_ic: List, + vk_alpha_g1: G1Point, + vk_beta_g2: G2Point, + vk_gamma_g2: G2Point, + vk_delta_g2: G2Point, + vk_ic: List, +} + +pub type PreparedGrothVerificationKey = { + vk: GrothVerificationKey, + vk_alpha_beta: G1Point, + vk_neg_gamma_g2: G2Point, + vk_delta_neg_g2: G2Point, } pub type GrothProof { - pi_a: common.G1Point, - pi_b: common.G2Point, - pi_c: common.G1Point, + pi_a: G1Point, + pi_b: G2Point, + pi_c: G1Point, } pub type GrothError { @@ -28,182 +36,52 @@ pub type GrothError { InvalidPublicInput } -pub type G1PointOrGrothError { - PGP(common.G1Point) - PGG(GrothError) +pub fn pairing(g1: G1Point, g2: G2Point) { + bls12_381_miller_loop( + bls12_381_g1_uncompress(g1), + bls12_381_g2_uncompress(g2), + ) } -pub type BoolOrGrothError { - BGB(Bool) - BGG(GrothError) +pub fn prepare_vk(vk: GrothVerificationKey) -> PreparedGrothVerificationKey { + todo } -// Main verification function +pub fn prepare_inputs(public_inputs: List) -> List { + todo +} + +// anticipates unprepared verification key and inputs pub fn verify( vk: GrothVerificationKey, proof: GrothProof, - public_inputs: List, -) -> BoolOrGrothError { - // Verify sizes match - expect - when verify_sizes(vk, public_inputs) is { - Some(err) -> { - trace BGG(err) - fail - } - None -> True - } - // Verify proof elements are valid - expect - when verify_proof_elements(proof) is { - Some(err) -> { - trace BGG(err) - fail - } - None -> True - } - // Prepare inputs (negate first element) - let prepared_inputs = prepare_inputs(public_inputs) - // Compute the linear combination of inputs with IC - when compute_linear_combination(vk.vk_ic, prepared_inputs) is { - PGG(err) -> BGG(err) - PGP(vk_x) -> { - // Perform pairing checks - let e_ab = pairing(proof.pi_a, proof.pi_b) - let e_alpha_beta = pairing(vk.vk_alpha_g1, vk.vk_beta_g2) - let e_vk_gamma = pairing(vk_x, vk.vk_gamma_g2) - let e_c_delta = pairing(proof.pi_c, vk.vk_delta_g2) - - // Final verification - let mlr1 = - builtin.bls12_381_mul_miller_loop_result(e_alpha_beta, e_vk_gamma) - let mlr2 = builtin.bls12_381_mul_miller_loop_result(mlr1, e_c_delta) - if builtin.bls12_381_final_verify(e_ab, mlr2) { - BGB(True) - } else { - BGG(PairingCheckFailed) - } - } - } -} - -// Helper function for pairing computation -// Optimized to use the standard library's BLS12-381 implementation more efficiently -fn pairing(g1: common.G1Point, g2: common.G2Point) { - // Convert G1Point to ByteArray - let g1_bytes = common.serialize_g1_point(g1) - // Convert G2Point to ByteArray - let g2_bytes = common.serialize_g2_point(g2) - // Use the standard library's decompress functions directly - let g1_element = g1.decompress(g1_bytes) - let g2_element = g2.decompress(g2_bytes) - // Perform the pairing - builtin.bls12_381_miller_loop(g1_element, g2_element) -} - -// Helper function to compute linear combination -fn compute_linear_combination( - ic: List, - inputs: List, -) -> G1PointOrGrothError { - when ic is { - [] -> PGG(InvalidVerificationKey) - [vk_0, ..rest] -> { - // Convert the first IC element to a G1 element - let vk_0_bytes = common.serialize_g1_point(vk_0) - let init_element = g1.decompress(vk_0_bytes) - // Combine the rest of the inputs - let result = combine_inputs(rest, inputs, init_element) - // Convert back to our G1Point representation - let result_bytes = g1.compress(result) - when common.g1_decompress(result_bytes) is { - Some(point) -> PGP(point) - None -> PGG(InvalidVerificationKey) - } - } - } -} - -// Optimized function to combine inputs using the standard library's BLS12-381 implementation -fn combine_inputs(ic: List, inputs: List, acc) { - when (ic, inputs) is { - ([], _) | (_, []) -> acc - ([vk_i, ..rest_ic], [input, ..rest_inputs]) -> { - // Convert the IC element to a G1 element - let vk_i_bytes = common.serialize_g1_point(vk_i) - let vk_i_element = g1.decompress(vk_i_bytes) - // Convert Field to Scalar for g1.scale - let scalar_input = - when scalar.new(input) is { - Some(s) -> s - None -> scalar.zero - } - // Multiply by the input and add to accumulator - let term = g1.scale(vk_i_element, scalar_input) - let new_acc = g1.add(acc, term) - // Continue with the rest of the inputs - combine_inputs(rest_ic, rest_inputs, new_acc) - } - } -} + inputs: List +) -> Bool { + // Prepare the verification key + let prepared_vk = prepare_vk(vk); -// Helper function to negate a field element -fn negate_field(x: common.Field) -> common.Field { - if x == 0 { - x - } else { - common.bls12_381_prime - x - } -} + // Prepare the public inputs + let prepared_inputs = prepare_inputs(inputs); -// Helper function to verify the proof size matches expected public input size -fn verify_sizes( - vk: GrothVerificationKey, - public_inputs: List, -) -> Option { - if list.length(public_inputs) != vk.n_public { - Some(InvalidPublicInput) - } else { - None - } + // Verify the proof using the prepared verification key and inputs + verify_prepared(prepared_vk, proof, prepared_inputs) } -// Helper function to prepare public inputs for verification -fn prepare_inputs(inputs: List) -> List { - // The first element should be negated as per the protocol - when inputs is { - [] -> [] - [first, ..rest] -> [negate_field(first), ..rest] - } -} +// anticipates prepared verification key and inputs +pub fn verify_prepared( + prepared_vk: PreparedGrothVerificationKey, + proof: GrothProof, + prepared_inputs: List +) -> Bool { + // Compute Linear Combination -// Helper function to verify proof elements are valid curve points -fn verify_proof_elements(proof: GrothProof) -> Option { - // Convert G1 points to ByteArray - let pi_a_bytes = common.serialize_g1_point(proof.pi_a) - let pi_c_bytes = common.serialize_g1_point(proof.pi_c) - // Convert G2 point to ByteArray - let pi_b_bytes = common.serialize_g2_point(proof.pi_b) - // Validate the points - let valid_a = - when common.g1_decompress(pi_a_bytes) is { - Some(_) -> True - None -> False - } - let valid_b = - when common.g2_decompress(pi_b_bytes) is { - Some(_) -> True - None -> False - } - let valid_c = - when common.g1_decompress(pi_c_bytes) is { - Some(_) -> True - None -> False - } + // Run the pairing check + let pairing_result = pairing(proof.pi_a, prepared_vk.vk_neg_gamma_g2) * + pairing(prepared_vk.vk_alpha_beta, proof.pi_b) * + pairing(prepared_vk.vk_delta_neg_g2, proof.pi_c); - if valid_a && valid_b && valid_c { - None - } else { - Some(InvalidProofFormat) - } -} + pairing_result == pairing( + prepared_vk.,vk_alpha_g1 + prepared_vk.vk_beta_g2 + ) +} \ No newline at end of file From 7edbae19f8b62dd267d951c7745c9c028f8a42fd Mon Sep 17 00:00:00 2001 From: samdelaney Date: Mon, 25 Aug 2025 19:00:06 -0700 Subject: [PATCH 2/7] 1.5 working groth implementations --- zkp/aiken.toml | 2 +- zkp/lib/groth/groth.ak | 36 ++++---------- zkp/lib/groth/groth2.ak | 102 ++++++++++++++++++++++++++++++++++++++++ zkp/lib/groth/groth3.ak | 86 +++++++++++++++++++++++++++++++++ zkp/plutus.json | 14 ++++++ 5 files changed, 212 insertions(+), 28 deletions(-) create mode 100644 zkp/lib/groth/groth2.ak create mode 100644 zkp/lib/groth/groth3.ak create mode 100644 zkp/plutus.json diff --git a/zkp/aiken.toml b/zkp/aiken.toml index 3e1ac32..f1ce231 100644 --- a/zkp/aiken.toml +++ b/zkp/aiken.toml @@ -1,6 +1,6 @@ name = "adao/zkp" version = "0.0.0" -compiler = "v1.1.12" +compiler = "v1.1.19" plutus = "v3" license = "Apache-2.0" description = "Aiken contracts for project 'adao/zkp'" diff --git a/zkp/lib/groth/groth.ak b/zkp/lib/groth/groth.ak index a861320..3822962 100644 --- a/zkp/lib/groth/groth.ak +++ b/zkp/lib/groth/groth.ak @@ -1,3 +1,9 @@ +use aiken/builtin.{ + bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, + bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, + bls12_381_mul_miller_loop_result, +} + pub type G1Point = ByteArray @@ -16,7 +22,7 @@ pub type GrothVerificationKey { vk_ic: List, } -pub type PreparedGrothVerificationKey = { +pub type PreparedGrothVerificationKey { vk: GrothVerificationKey, vk_alpha_beta: G1Point, vk_neg_gamma_g2: G2Point, @@ -43,30 +49,6 @@ pub fn pairing(g1: G1Point, g2: G2Point) { ) } -pub fn prepare_vk(vk: GrothVerificationKey) -> PreparedGrothVerificationKey { - todo -} - -pub fn prepare_inputs(public_inputs: List) -> List { - todo -} - -// anticipates unprepared verification key and inputs -pub fn verify( - vk: GrothVerificationKey, - proof: GrothProof, - inputs: List -) -> Bool { - // Prepare the verification key - let prepared_vk = prepare_vk(vk); - - // Prepare the public inputs - let prepared_inputs = prepare_inputs(inputs); - - // Verify the proof using the prepared verification key and inputs - verify_prepared(prepared_vk, proof, prepared_inputs) -} - // anticipates prepared verification key and inputs pub fn verify_prepared( prepared_vk: PreparedGrothVerificationKey, @@ -78,10 +60,10 @@ pub fn verify_prepared( // Run the pairing check let pairing_result = pairing(proof.pi_a, prepared_vk.vk_neg_gamma_g2) * pairing(prepared_vk.vk_alpha_beta, proof.pi_b) * - pairing(prepared_vk.vk_delta_neg_g2, proof.pi_c); + pairing(prepared_vk.vk_delta_neg_g2, proof.pi_c) pairing_result == pairing( - prepared_vk.,vk_alpha_g1 + prepared_vk.vk_alpha_g1 prepared_vk.vk_beta_g2 ) } \ No newline at end of file diff --git a/zkp/lib/groth/groth2.ak b/zkp/lib/groth/groth2.ak new file mode 100644 index 0000000..e63e7e6 --- /dev/null +++ b/zkp/lib/groth/groth2.ak @@ -0,0 +1,102 @@ +use aiken/builtin.{ + bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, + bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, +} +use aiken/collection/list + +const q = + 21888242871839275222246405745257275088696311157297823662689037894645226208583 + +pub type Proof { + a: G1Element, + b: G2Element, + c: G1Element, +} + +pub type VerifierKey { + alpha: G1Element, + beta: G2Element, + gamma: G2Element, + delta: G2Element, + ic0: G1Element, + ic1: G1Element, +} + + + +// Pairing check (stub, replace with actual implementation) +pub fn pairing_check(points: List) -> Bool { + // Implement or call your library's pairing check + True +} + +// Main verification function +pub fn verify(vk: VerifierKey, proof: Proof, input: List) -> Bool { + let k1 = bls12_381_g1_scalar_mul(vk.ic0, list.head(input)) + let k2 = bls12_381_g1_scalar_mul(vk.ic1, list.head(list.tail(input))) + let k = bls12_381_g1_add(k1, k2) + + pairing_check( + proof.a, + proof.b, + proof.c, + vk.alpha, + vk.beta, + vk.gamma, + vk.delta, + k + ) +} + +// Emulate verification +pub fn emulate() -> Bool { + let vk = verifier_key() + let proof = proof() + let input = input() + verify(vk, proof, input) +} + +// Hardcoded input values +pub fn input() -> List { + list.range(1, 104) +} + +pub fn verifier_key() -> VerifierKey { + VerifierKey { + alpha: G1Element { + x: 1368015179489954701390400359078579693043519447331113978918064868415326638035, + y: 9918110051302171585080402603319702774565515993150576347155970296011118125764, + }, + beta: G2Element { + x1: 2725019753478801796453339367788033689375851816420509565303521482350756874229, + x2: 7273165102799931111715871471550377909735733521218303035754523677688038059653, + y1: 2512659008974376214222774206987427162027254181373325676825515531566330959255, + y2: 957874124722006818841961785324909313781880061366718538693995380805373202866, + }, + gamma: G2Element { + x1: 18936818173480011669507163011118288089468827259971823710084038754632518263340, + x2: 18556147586753789634670778212244811446448229326945855846642767021074501673839, + y1: 18825831177813899069786213865729385895767511805925522466244528695074736584695, + y2: 13775476761357503446238925910346030822904460488609979964814810757616608848118, + }, + delta: G2Element { + x1: 20954117799226682825035885491234530437475518021362091509513177301640194298072, + x2: 4540444681147253467785307942530223364530218361853237193970751657229138047649, + y1: 21508930868448350162258892668132814424284302804699005394342512102884055673846, + y2: 11631839690097995216017572651900167465857396346217730511548857041925508482915, + }, + ic0: G1Element { x: 0, y: 0 }, + ic1: G1Element { + x: 1540147615742092855122362390273215696202300989980535937807544369063691019287, + y: 916302540883947080468652904864832717784863855769927076757632797189693955321, + }, + } +} + +fn proof() -> Proof { + Proof { + a: bls12_381_g1_uncompress(#"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272"), + b: bls12_381_g2_uncompress(#"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52"), + c: bls12_381_g1_uncompress(#"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981"), + } +} \ No newline at end of file diff --git a/zkp/lib/groth/groth3.ak b/zkp/lib/groth/groth3.ak new file mode 100644 index 0000000..a78795f --- /dev/null +++ b/zkp/lib/groth/groth3.ak @@ -0,0 +1,86 @@ +use aiken/builtin.{ + bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, + bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, + bls12_381_mul_miller_loop_result, +} + +pub type SnarkVerificationKey { + nPublic: Int, + // G1Element + vkAlpha: ByteArray, + // G2Element + vkBeta: ByteArray, + // G2Element + vkGamma: ByteArray, + // G2Element + vkDelta: ByteArray, + // List + vkAlphaBeta: List, + // List + vkIC: List, +} + +// +pub type Proof { + // G1Element + piA: ByteArray, + // G2Element + piB: ByteArray, + // G1Element + piC: ByteArray, +} + +pub fn pairing(g1: ByteArray, g2: ByteArray) { + bls12_381_miller_loop( + bls12_381_g1_uncompress(g1), + bls12_381_g2_uncompress(g2), + ) +} + +pub fn derive( + vk_ic: List, + public: List, + result: G1Element, +) -> G1Element { + when vk_ic is { + [] -> result + [i, ..vk_ic] -> + when public is { + [] -> fail + [scalar, ..public] -> + derive( + vk_ic, + public, + bls12_381_g1_add( + result, + bls12_381_g1_scalar_mul(scalar, bls12_381_g1_uncompress(i)), + ), + ) + } + } +} + +pub fn groth_verify( + vk: SnarkVerificationKey, + proof: Proof, + public: List, +) -> Bool { + // let n = vk.nPublic + let eAB = pairing(proof.piA, proof.piB) + let eAlphaBeta = pairing(vk.vkAlpha, vk.vkBeta) + + let vkI = + when vk.vkIC is { + [] -> fail @"empty vkIC?" + [head, ..tail] -> derive(tail, public, bls12_381_g1_uncompress(head)) + } + + let eIGamma = bls12_381_miller_loop(vkI, bls12_381_g2_uncompress(vk.vkGamma)) + let eCDelta = pairing(proof.piC, vk.vkDelta) + + // * Miller functions + let mlr1 = bls12_381_mul_miller_loop_result(eAlphaBeta, eIGamma) + let mlr2 = bls12_381_mul_miller_loop_result(mlr1, eCDelta) + + bls12_381_final_verify(eAB, mlr2) +} \ No newline at end of file diff --git a/zkp/plutus.json b/zkp/plutus.json new file mode 100644 index 0000000..852267f --- /dev/null +++ b/zkp/plutus.json @@ -0,0 +1,14 @@ +{ + "preamble": { + "title": "adao/zkp", + "description": "Aiken contracts for project 'adao/zkp'", + "version": "0.0.0", + "plutusVersion": "v3", + "compiler": { + "name": "Aiken", + "version": "v1.1.15+f03633e" + }, + "license": "Apache-2.0" + }, + "validators": [] +} \ No newline at end of file From 17832654c5f56c146b414153a2c08833eaec397b Mon Sep 17 00:00:00 2001 From: samdelaney Date: Tue, 26 Aug 2025 14:03:26 -0700 Subject: [PATCH 3/7] uncompressed groth implementation builds --- zkp/lib/groth/groth.ak | 177 +++++++++++++++++++++++++++++----------- zkp/lib/groth/groth2.ak | 102 ----------------------- zkp/lib/groth/groth3.ak | 86 ------------------- 3 files changed, 129 insertions(+), 236 deletions(-) delete mode 100644 zkp/lib/groth/groth2.ak delete mode 100644 zkp/lib/groth/groth3.ak diff --git a/zkp/lib/groth/groth.ak b/zkp/lib/groth/groth.ak index 3822962..8e523eb 100644 --- a/zkp/lib/groth/groth.ak +++ b/zkp/lib/groth/groth.ak @@ -1,69 +1,150 @@ use aiken/builtin.{ bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, - bls12_381_mul_miller_loop_result, + bls12_381_mul_miller_loop_result } +use aiken/collection/list -pub type G1Point = - ByteArray - -pub type G2Point = - ByteArray +pub type CompressedProof { + a: ByteArray, + b: ByteArray, + c: ByteArray, +} -pub type Field = - Int +pub type CompressedVK { + alpha: ByteArray, + beta: ByteArray, + gamma: ByteArray, + delta: ByteArray, + ic0: ByteArray, + ic1: ByteArray, +} -pub type GrothVerificationKey { - n_public: Int, - vk_alpha_g1: G1Point, - vk_beta_g2: G2Point, - vk_gamma_g2: G2Point, - vk_delta_g2: G2Point, - vk_ic: List, +pub type Proof { + a: G1Element, + b: G2Element, + c: G1Element, } -pub type PreparedGrothVerificationKey { - vk: GrothVerificationKey, - vk_alpha_beta: G1Point, - vk_neg_gamma_g2: G2Point, - vk_delta_neg_g2: G2Point, +pub type VerifierKey { + alpha: G1Element, + beta: G2Element, + gamma: G2Element, + delta: G2Element, + ic0: G1Element, + ic1: G1Element, } -pub type GrothProof { - pi_a: G1Point, - pi_b: G2Point, - pi_c: G1Point, +pub fn uncompress_proof(c: CompressedProof) -> Proof { + Proof { + a: bls12_381_g1_uncompress(c.a), + b: bls12_381_g2_uncompress(c.b), + c: bls12_381_g1_uncompress(c.c), + } } -pub type GrothError { - InvalidProofFormat - InvalidVerificationKey - PairingCheckFailed - InvalidPublicInput +pub fn uncompress_vk(c: CompressedVK) -> VerifierKey { + VerifierKey { + alpha: bls12_381_g1_uncompress(c.alpha), + beta: bls12_381_g2_uncompress(c.beta), + gamma: bls12_381_g2_uncompress(c.gamma), + delta: bls12_381_g2_uncompress(c.delta), + ic0: bls12_381_g1_uncompress(c.ic0), + ic1: bls12_381_g1_uncompress(c.ic1), + } } -pub fn pairing(g1: G1Point, g2: G2Point) { - bls12_381_miller_loop( - bls12_381_g1_uncompress(g1), - bls12_381_g2_uncompress(g2), - ) +pub fn verify_compressed( + vk: CompressedVK, + proof: CompressedProof, + input: List +){ + let vk = uncompress_vk(vk) + let proof = uncompress_proof(proof) + verify(vk, proof, input) } -// anticipates prepared verification key and inputs -pub fn verify_prepared( - prepared_vk: PreparedGrothVerificationKey, - proof: GrothProof, - prepared_inputs: List +pub fn pairing_check( + a: G1Element, + b: G2Element, + c: G1Element, + delta: G2Element, + alpha: G1Element, + beta: G2Element, + k: G1Element, + gamma: G2Element ) -> Bool { - // Compute Linear Combination + // e(A,B) = e(α,β) ∙ e(C,δ) ∙ e(K,γ) + // e: miller loop + // ∙: mul miller loop + // =: final verify - // Run the pairing check - let pairing_result = pairing(proof.pi_a, prepared_vk.vk_neg_gamma_g2) * - pairing(prepared_vk.vk_alpha_beta, proof.pi_b) * - pairing(prepared_vk.vk_delta_neg_g2, proof.pi_c) + // Pair Components w/ Miller Loop + let ab = bls12_381_miller_loop(a, b) + let alphabeta = bls12_381_miller_loop(alpha, beta) + + let kgamma = bls12_381_miller_loop(k, gamma) + let cdelta = bls12_381_miller_loop(c, delta) + + // Combine Miller Loop Results + let mlr1 = bls12_381_mul_miller_loop_result(alphabeta, kgamma) + let mlr2 = bls12_381_mul_miller_loop_result(mlr1, cdelta) + + // Final Equality Check + bls12_381_final_verify(ab, mlr2) +} - pairing_result == pairing( - prepared_vk.vk_alpha_g1 - prepared_vk.vk_beta_g2 +// Main verification function +pub fn verify(vk: VerifierKey, proof: Proof, input: List) -> Bool { + + // Construct K + let k1 = when list.head(input) is { + Some(x) -> bls12_381_g1_scalar_mul(x, vk.ic0) + None -> vk.ic0 // or handle error appropriately + } + let k2 = when list.tail(input) is { + Some(tail) -> when list.head(tail) is { + Some(x) -> bls12_381_g1_scalar_mul(x, vk.ic1) + None -> vk.ic1 // handle empty tail + } + None -> vk.ic1 // handle empty input + } + let k = bls12_381_g1_add(k1, k2) + + // Pairing check + pairing_check( + proof.a, + proof.b, + proof.c, + vk.delta, + vk.alpha, + vk.beta, + k, + vk.gamma ) -} \ No newline at end of file +} + +// Emulate verification +// pub fn emulate() -> Bool { +// let vk = verifier_key() +// let proof = proof() +// let input = input() +// verify(vk, proof, input) +// } + +// // Hardcoded input values +// pub fn input() -> List { +// list.range(1, 104) +// } + +// pub fn verifier_key() -> VerifierKey { +// TODO +// } + +// fn proof() -> Proof { +// Proof { +// a: bls12_381_g1_uncompress(#"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272"), +// b: bls12_381_g2_uncompress(#"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52"), +// c: bls12_381_g1_uncompress(#"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981"), +// } +// } \ No newline at end of file diff --git a/zkp/lib/groth/groth2.ak b/zkp/lib/groth/groth2.ak deleted file mode 100644 index e63e7e6..0000000 --- a/zkp/lib/groth/groth2.ak +++ /dev/null @@ -1,102 +0,0 @@ -use aiken/builtin.{ - bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, - bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, -} -use aiken/collection/list - -const q = - 21888242871839275222246405745257275088696311157297823662689037894645226208583 - -pub type Proof { - a: G1Element, - b: G2Element, - c: G1Element, -} - -pub type VerifierKey { - alpha: G1Element, - beta: G2Element, - gamma: G2Element, - delta: G2Element, - ic0: G1Element, - ic1: G1Element, -} - - - -// Pairing check (stub, replace with actual implementation) -pub fn pairing_check(points: List) -> Bool { - // Implement or call your library's pairing check - True -} - -// Main verification function -pub fn verify(vk: VerifierKey, proof: Proof, input: List) -> Bool { - let k1 = bls12_381_g1_scalar_mul(vk.ic0, list.head(input)) - let k2 = bls12_381_g1_scalar_mul(vk.ic1, list.head(list.tail(input))) - let k = bls12_381_g1_add(k1, k2) - - pairing_check( - proof.a, - proof.b, - proof.c, - vk.alpha, - vk.beta, - vk.gamma, - vk.delta, - k - ) -} - -// Emulate verification -pub fn emulate() -> Bool { - let vk = verifier_key() - let proof = proof() - let input = input() - verify(vk, proof, input) -} - -// Hardcoded input values -pub fn input() -> List { - list.range(1, 104) -} - -pub fn verifier_key() -> VerifierKey { - VerifierKey { - alpha: G1Element { - x: 1368015179489954701390400359078579693043519447331113978918064868415326638035, - y: 9918110051302171585080402603319702774565515993150576347155970296011118125764, - }, - beta: G2Element { - x1: 2725019753478801796453339367788033689375851816420509565303521482350756874229, - x2: 7273165102799931111715871471550377909735733521218303035754523677688038059653, - y1: 2512659008974376214222774206987427162027254181373325676825515531566330959255, - y2: 957874124722006818841961785324909313781880061366718538693995380805373202866, - }, - gamma: G2Element { - x1: 18936818173480011669507163011118288089468827259971823710084038754632518263340, - x2: 18556147586753789634670778212244811446448229326945855846642767021074501673839, - y1: 18825831177813899069786213865729385895767511805925522466244528695074736584695, - y2: 13775476761357503446238925910346030822904460488609979964814810757616608848118, - }, - delta: G2Element { - x1: 20954117799226682825035885491234530437475518021362091509513177301640194298072, - x2: 4540444681147253467785307942530223364530218361853237193970751657229138047649, - y1: 21508930868448350162258892668132814424284302804699005394342512102884055673846, - y2: 11631839690097995216017572651900167465857396346217730511548857041925508482915, - }, - ic0: G1Element { x: 0, y: 0 }, - ic1: G1Element { - x: 1540147615742092855122362390273215696202300989980535937807544369063691019287, - y: 916302540883947080468652904864832717784863855769927076757632797189693955321, - }, - } -} - -fn proof() -> Proof { - Proof { - a: bls12_381_g1_uncompress(#"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272"), - b: bls12_381_g2_uncompress(#"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52"), - c: bls12_381_g1_uncompress(#"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981"), - } -} \ No newline at end of file diff --git a/zkp/lib/groth/groth3.ak b/zkp/lib/groth/groth3.ak deleted file mode 100644 index a78795f..0000000 --- a/zkp/lib/groth/groth3.ak +++ /dev/null @@ -1,86 +0,0 @@ -use aiken/builtin.{ - bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, - bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, - bls12_381_mul_miller_loop_result, -} - -pub type SnarkVerificationKey { - nPublic: Int, - // G1Element - vkAlpha: ByteArray, - // G2Element - vkBeta: ByteArray, - // G2Element - vkGamma: ByteArray, - // G2Element - vkDelta: ByteArray, - // List - vkAlphaBeta: List, - // List - vkIC: List, -} - -// -pub type Proof { - // G1Element - piA: ByteArray, - // G2Element - piB: ByteArray, - // G1Element - piC: ByteArray, -} - -pub fn pairing(g1: ByteArray, g2: ByteArray) { - bls12_381_miller_loop( - bls12_381_g1_uncompress(g1), - bls12_381_g2_uncompress(g2), - ) -} - -pub fn derive( - vk_ic: List, - public: List, - result: G1Element, -) -> G1Element { - when vk_ic is { - [] -> result - [i, ..vk_ic] -> - when public is { - [] -> fail - [scalar, ..public] -> - derive( - vk_ic, - public, - bls12_381_g1_add( - result, - bls12_381_g1_scalar_mul(scalar, bls12_381_g1_uncompress(i)), - ), - ) - } - } -} - -pub fn groth_verify( - vk: SnarkVerificationKey, - proof: Proof, - public: List, -) -> Bool { - // let n = vk.nPublic - let eAB = pairing(proof.piA, proof.piB) - let eAlphaBeta = pairing(vk.vkAlpha, vk.vkBeta) - - let vkI = - when vk.vkIC is { - [] -> fail @"empty vkIC?" - [head, ..tail] -> derive(tail, public, bls12_381_g1_uncompress(head)) - } - - let eIGamma = bls12_381_miller_loop(vkI, bls12_381_g2_uncompress(vk.vkGamma)) - let eCDelta = pairing(proof.piC, vk.vkDelta) - - // * Miller functions - let mlr1 = bls12_381_mul_miller_loop_result(eAlphaBeta, eIGamma) - let mlr2 = bls12_381_mul_miller_loop_result(mlr1, eCDelta) - - bls12_381_final_verify(eAB, mlr2) -} \ No newline at end of file From 33a37f67d0504a998cd99bb8a8b30cac5bbe95c1 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Thu, 18 Sep 2025 17:14:34 -0700 Subject: [PATCH 4/7] support more public inputs, add tests --- zkp/lib/groth/groth.ak | 163 +++++++++++++++++++++++++++++------------ 1 file changed, 118 insertions(+), 45 deletions(-) diff --git a/zkp/lib/groth/groth.ak b/zkp/lib/groth/groth.ak index 8e523eb..7b8d425 100644 --- a/zkp/lib/groth/groth.ak +++ b/zkp/lib/groth/groth.ak @@ -16,8 +16,7 @@ pub type CompressedVK { beta: ByteArray, gamma: ByteArray, delta: ByteArray, - ic0: ByteArray, - ic1: ByteArray, + vkIC: List, } pub type Proof { @@ -31,8 +30,7 @@ pub type VerifierKey { beta: G2Element, gamma: G2Element, delta: G2Element, - ic0: G1Element, - ic1: G1Element, + vkIC: List, } pub fn uncompress_proof(c: CompressedProof) -> Proof { @@ -49,19 +47,18 @@ pub fn uncompress_vk(c: CompressedVK) -> VerifierKey { beta: bls12_381_g2_uncompress(c.beta), gamma: bls12_381_g2_uncompress(c.gamma), delta: bls12_381_g2_uncompress(c.delta), - ic0: bls12_381_g1_uncompress(c.ic0), - ic1: bls12_381_g1_uncompress(c.ic1), + vkIC: list.map(c.vkIC, fn(c_ic) { bls12_381_g1_uncompress(c_ic)}), } } pub fn verify_compressed( vk: CompressedVK, proof: CompressedProof, - input: List + inputs: List ){ let vk = uncompress_vk(vk) let proof = uncompress_proof(proof) - verify(vk, proof, input) + verify(vk, proof, inputs) } pub fn pairing_check( @@ -95,21 +92,12 @@ pub fn pairing_check( } // Main verification function -pub fn verify(vk: VerifierKey, proof: Proof, input: List) -> Bool { +pub fn verify(vk: VerifierKey, proof: Proof, inputs: List) -> Bool { - // Construct K - let k1 = when list.head(input) is { - Some(x) -> bls12_381_g1_scalar_mul(x, vk.ic0) - None -> vk.ic0 // or handle error appropriately + let k = when vk.vkIC is { + [] -> fail @"empty vkIC?" + [head, ..tail] -> derive(tail, inputs, head) } - let k2 = when list.tail(input) is { - Some(tail) -> when list.head(tail) is { - Some(x) -> bls12_381_g1_scalar_mul(x, vk.ic1) - None -> vk.ic1 // handle empty tail - } - None -> vk.ic1 // handle empty input - } - let k = bls12_381_g1_add(k1, k2) // Pairing check pairing_check( @@ -124,27 +112,112 @@ pub fn verify(vk: VerifierKey, proof: Proof, input: List) -> Bool { ) } -// Emulate verification -// pub fn emulate() -> Bool { -// let vk = verifier_key() -// let proof = proof() -// let input = input() -// verify(vk, proof, input) -// } - -// // Hardcoded input values -// pub fn input() -> List { -// list.range(1, 104) -// } - -// pub fn verifier_key() -> VerifierKey { -// TODO -// } - -// fn proof() -> Proof { -// Proof { -// a: bls12_381_g1_uncompress(#"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272"), -// b: bls12_381_g2_uncompress(#"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52"), -// c: bls12_381_g1_uncompress(#"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981"), -// } -// } \ No newline at end of file +pub fn derive( + vk_ic: List, + public: List, + result: G1Element, +) -> G1Element { + when vk_ic is { + [] -> result + [i, ..vk_ic] -> + when public is { + [] -> fail + [scalar, ..public] -> + derive( + vk_ic, + public, + bls12_381_g1_add( + result, + bls12_381_g1_scalar_mul(scalar, i), + ), + ) + } + } +} + +test groth_verify_pass_1() { + // Template of VK + let vk: CompressedVK = + CompressedVK { + alpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + beta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + gamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + delta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: CompressedProof = + CompressedProof { + a: #"8b84d092731c653b1accdda79c51e3f5d289bed7311189d927deadef0470e437e6d1d400634726512a79a015867424e3", + b: #"92cb1c125816e4b522c7f430a5d74a61116b6189de7b2341f040194c02f10d9ef0cf081f4029444a65ea74e69d98b1cf08d3864087d5d2dee2ed6ab102f9b78e65d341f0824341a9fc25d0ea9dacccc5d355b4eddb0057949370a19c47135b0e", + c: #"a4ef633c858a3ff194db50eacdf715f7296fb3d1202c54b543284e9656b69aa90f33ac0e2572d3ab847b88268dcd1f7e", + } + // Template of public values + let public_values: List = + [561, 3] + + verify_compressed(vk, pk, public_values) +} + +test groth_verify_fail_1() fail { + // Template of VK + let vk: CompressedVK = + CompressedVK { + alpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + beta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + gamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + delta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: CompressedProof = + CompressedProof { + a: #"a4ef633c858a3ff194db50eacdf715f7296fb3d1202c54b543284e9656b69aa90f33ac0e2572d3ab847b88268dcd1f7e", + b: #"92cb1c125816e4b522c7f430a5d74a61116b6189de7b2341f040194c02f10d9ef0cf081f4029444a65ea74e69d98b1cf08d3864087d5d2dee2ed6ab102f9b78e65d341f0824341a9fc25d0ea9dacccc5d355b4eddb0057949370a19c47135b0e", + c: #"8b84d092731c653b1accdda79c51e3f5d289bed7311189d927deadef0470e437e6d1d400634726512a79a015867424e3", + } + // Template of public values + let public_values: List = + [561, 3] + + verify_compressed(vk, pk, public_values) +} + +test groth_verify_pass_2() { + // Template of VK + let vk: CompressedVK = + CompressedVK { + alpha: #"8e3d9e248feda194cb6fa0a3b64fd2a380cb5e94836bf8148bf97ebcbb5819d9a78f63102f0293c104bcbb2f810d8eb4", + beta: #"8cd68a7186a908212680a0234d8210c20328f8fb3ce1d69c9aec9330a5802d6cfaf6d7cf3176133221c19188590cb4141874ea7bbfcb9872931e115d882c46b90c3dcbcee10062d1c9b9b0a691d7bec7d2735f06495c7f71dea210e55b2782df", + gamma: #"93e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + delta: #"938231fcec443fbdeb1079ff126b8f69bd8579ffe82d39923214d4345395beee60200288fa20c97ae50f3212131b6f8802af2f9f515c65af6a9a6c294c738590104376a0af44731d6699db6a286608774243f7d1dddc4605eb340e65e15060a5", + vkIC: [ + #"b5813c90d3455acb8608fdf66e8601f24ef048f3fdf9384862d77c72cb5cddfde2b307976b1b0319c42ba985f94be60a", + #"a41a0e6370c054be0f9acce08e97f6d5702d9daa9e9a934e8a377f553593baa1c58062adc73d63558653422d54d6f50c", + #"8e02a87c519c3145f984d25fdf769f74fbc36626c385d4554fb4bc1d7a12cbf669d40f257023b8b3c9a31e631aa8f981", + ], + } + + // Template of Proof + let pk: CompressedProof = + CompressedProof { + a: #"98ca847cc04a6f67ac85a628521450323d7aa5335d4c2c48e9780b659cf7ea8ece2d0b305c9ff9dcfb3e548d61bbaebe", + b: #"a8e6ba4dbce6aa84de8ca1cd39d42353fcac89fe8cb800e728ada3ca4ae3b07baa68f76b9e4fa73eebf78cc609fa85d6166a3b69cd08cc59f2ff36e52dfdf231540a4212fdd4a142504c76066bddea342dd0183b2b11ed62cfc1497189a4db52", + c: #"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272", + } + // Template of public values + let public_values: List = + [8827, 7] + + verify_compressed(vk, pk, public_values) +} \ No newline at end of file From bfece397632fdf1d5042ff66f88e0d891d634a0e Mon Sep 17 00:00:00 2001 From: samdelaney Date: Thu, 18 Sep 2025 17:22:18 -0700 Subject: [PATCH 5/7] fix formatting --- zkp/lib/groth/groth.ak | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/zkp/lib/groth/groth.ak b/zkp/lib/groth/groth.ak index 7b8d425..157674b 100644 --- a/zkp/lib/groth/groth.ak +++ b/zkp/lib/groth/groth.ak @@ -1,7 +1,7 @@ use aiken/builtin.{ bls12_381_final_verify, bls12_381_g1_add, bls12_381_g1_scalar_mul, bls12_381_g1_uncompress, bls12_381_g2_uncompress, bls12_381_miller_loop, - bls12_381_mul_miller_loop_result + bls12_381_mul_miller_loop_result, } use aiken/collection/list @@ -47,15 +47,15 @@ pub fn uncompress_vk(c: CompressedVK) -> VerifierKey { beta: bls12_381_g2_uncompress(c.beta), gamma: bls12_381_g2_uncompress(c.gamma), delta: bls12_381_g2_uncompress(c.delta), - vkIC: list.map(c.vkIC, fn(c_ic) { bls12_381_g1_uncompress(c_ic)}), + vkIC: list.map(c.vkIC, fn(c_ic) { bls12_381_g1_uncompress(c_ic) }), } } pub fn verify_compressed( vk: CompressedVK, proof: CompressedProof, - inputs: List -){ + inputs: List, +) { let vk = uncompress_vk(vk) let proof = uncompress_proof(proof) verify(vk, proof, inputs) @@ -69,7 +69,7 @@ pub fn pairing_check( alpha: G1Element, beta: G2Element, k: G1Element, - gamma: G2Element + gamma: G2Element, ) -> Bool { // e(A,B) = e(α,β) ∙ e(C,δ) ∙ e(K,γ) // e: miller loop @@ -93,11 +93,11 @@ pub fn pairing_check( // Main verification function pub fn verify(vk: VerifierKey, proof: Proof, inputs: List) -> Bool { - - let k = when vk.vkIC is { - [] -> fail @"empty vkIC?" - [head, ..tail] -> derive(tail, inputs, head) - } + let k = + when vk.vkIC is { + [] -> fail @"empty vkIC?" + [head, ..tail] -> derive(tail, inputs, head) + } // Pairing check pairing_check( @@ -108,7 +108,7 @@ pub fn verify(vk: VerifierKey, proof: Proof, inputs: List) -> Bool { vk.alpha, vk.beta, k, - vk.gamma + vk.gamma, ) } @@ -126,10 +126,7 @@ pub fn derive( derive( vk_ic, public, - bls12_381_g1_add( - result, - bls12_381_g1_scalar_mul(scalar, i), - ), + bls12_381_g1_add(result, bls12_381_g1_scalar_mul(scalar, i)), ) } } @@ -158,8 +155,7 @@ test groth_verify_pass_1() { c: #"a4ef633c858a3ff194db50eacdf715f7296fb3d1202c54b543284e9656b69aa90f33ac0e2572d3ab847b88268dcd1f7e", } // Template of public values - let public_values: List = - [561, 3] + let public_values: List = [561, 3] verify_compressed(vk, pk, public_values) } @@ -187,8 +183,7 @@ test groth_verify_fail_1() fail { c: #"8b84d092731c653b1accdda79c51e3f5d289bed7311189d927deadef0470e437e6d1d400634726512a79a015867424e3", } // Template of public values - let public_values: List = - [561, 3] + let public_values: List = [561, 3] verify_compressed(vk, pk, public_values) } @@ -216,8 +211,7 @@ test groth_verify_pass_2() { c: #"8bc8cc3f11483138cc55d5f0389e67231f9e8465e5cb4a5a668e6e298d5c4febb2a18e86881c84dd03c5d33db65af272", } // Template of public values - let public_values: List = - [8827, 7] + let public_values: List = [8827, 7] verify_compressed(vk, pk, public_values) -} \ No newline at end of file +} From 8941a476db3e67c1a77d3ba40dcee2c40f076287 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Thu, 18 Sep 2025 17:33:28 -0700 Subject: [PATCH 6/7] update setup-aiken --- .github/workflows/continuous-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index a96409e..588e5b4 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - uses: aiken-lang/setup-aiken@v1 + - uses: aiken-lang/setup-aiken@v1.0.3 with: version: v1.1.12 - run: aiken fmt --check From bbbf62f33534c1e55adbce1340fb2e9ec5867b07 Mon Sep 17 00:00:00 2001 From: samdelaney Date: Thu, 18 Sep 2025 17:35:32 -0700 Subject: [PATCH 7/7] update aiken version in ci --- .github/workflows/continuous-integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 588e5b4..dab15f6 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v3 - uses: aiken-lang/setup-aiken@v1.0.3 with: - version: v1.1.12 + version: v1.1.19 - run: aiken fmt --check working-directory: zkp - run: aiken check -D