Skip to content
Merged
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
20 changes: 10 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,20 @@ jobs:
uses: dtolnay/rust-toolchain@stable

- name: Build halo2 shared library
working-directory: zeroj-verifier-halo2/halo2-rust
working-directory: incubator/zeroj-verifier-halo2/halo2-rust
run: cargo build --release

- name: Copy library to resource path
run: |
mkdir -p zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}
cp zeroj-verifier-halo2/halo2-rust/target/release/${{ matrix.lib }} \
zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/
mkdir -p incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}
cp incubator/zeroj-verifier-halo2/halo2-rust/target/release/${{ matrix.lib }} \
incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/

- name: Upload native library
uses: actions/upload-artifact@v4
with:
name: halo2-native-${{ matrix.os }}
path: zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/${{ matrix.lib }}
path: incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/${{ matrix.lib }}
retention-days: 1

# ================================================================
Expand Down Expand Up @@ -127,26 +127,26 @@ jobs:
uses: actions/download-artifact@v4
with:
name: halo2-native-linux-x86_64
path: zeroj-verifier-halo2/src/main/resources/native/linux-x86_64/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/linux-x86_64/

- name: Download halo2 native (linux-arm64)
uses: actions/download-artifact@v4
with:
name: halo2-native-linux-arm64
path: zeroj-verifier-halo2/src/main/resources/native/linux-arm64/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/linux-arm64/

- name: Download halo2 native (macos-arm64)
uses: actions/download-artifact@v4
with:
name: halo2-native-macos-arm64
path: zeroj-verifier-halo2/src/main/resources/native/macos-arm64/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/macos-arm64/

- name: Verify native libraries are in place
run: |
echo "=== gnark native libraries ==="
find zeroj-prover-gnark/src/main/resources/native -type f
echo "=== halo2 native libraries ==="
find zeroj-verifier-halo2/src/main/resources/native -type f
find incubator/zeroj-verifier-halo2/src/main/resources/native -type f

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down Expand Up @@ -199,7 +199,7 @@ jobs:
uses: actions/download-artifact@v4
with:
name: halo2-native-${{ matrix.os }}
path: zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,20 @@ jobs:
uses: dtolnay/rust-toolchain@stable

- name: Build halo2 shared library
working-directory: zeroj-verifier-halo2/halo2-rust
working-directory: incubator/zeroj-verifier-halo2/halo2-rust
run: cargo build --release

- name: Copy library to resource path
run: |
mkdir -p zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}
cp zeroj-verifier-halo2/halo2-rust/target/release/${{ matrix.lib }} \
zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/
mkdir -p incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}
cp incubator/zeroj-verifier-halo2/halo2-rust/target/release/${{ matrix.lib }} \
incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/

- name: Upload native library
uses: actions/upload-artifact@v4
with:
name: halo2-native-${{ matrix.os }}
path: zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/${{ matrix.lib }}
path: incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/${{ matrix.lib }}
retention-days: 1

# ================================================================
Expand Down Expand Up @@ -125,14 +125,14 @@ jobs:
cp gnark-native-$platform/* zeroj-prover-gnark/src/main/resources/native/$platform/ || true

# halo2
mkdir -p zeroj-verifier-halo2/src/main/resources/native/$platform
cp halo2-native-$platform/* zeroj-verifier-halo2/src/main/resources/native/$platform/ || true
mkdir -p incubator/zeroj-verifier-halo2/src/main/resources/native/$platform
cp halo2-native-$platform/* incubator/zeroj-verifier-halo2/src/main/resources/native/$platform/ || true
done

echo "=== gnark native libraries ==="
find zeroj-prover-gnark/src/main/resources/native -type f
echo "=== halo2 native libraries ==="
find zeroj-verifier-halo2/src/main/resources/native -type f
find incubator/zeroj-verifier-halo2/src/main/resources/native -type f

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down
18 changes: 9 additions & 9 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,20 @@ jobs:
uses: dtolnay/rust-toolchain@stable

- name: Build halo2 shared library
working-directory: zeroj-verifier-halo2/halo2-rust
working-directory: incubator/zeroj-verifier-halo2/halo2-rust
run: cargo build --release

- name: Copy library to resource path
run: |
mkdir -p zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}
cp zeroj-verifier-halo2/halo2-rust/target/release/${{ matrix.lib }} \
zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/
mkdir -p incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}
cp incubator/zeroj-verifier-halo2/halo2-rust/target/release/${{ matrix.lib }} \
incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/

- name: Upload native library
uses: actions/upload-artifact@v4
with:
name: halo2-native-${{ matrix.os }}
path: zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/${{ matrix.lib }}
path: incubator/zeroj-verifier-halo2/src/main/resources/native/${{ matrix.os }}/${{ matrix.lib }}
retention-days: 1

# ================================================================
Expand Down Expand Up @@ -126,26 +126,26 @@ jobs:
uses: actions/download-artifact@v4
with:
name: halo2-native-linux-x86_64
path: zeroj-verifier-halo2/src/main/resources/native/linux-x86_64/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/linux-x86_64/

- name: Download halo2 native (linux-arm64)
uses: actions/download-artifact@v4
with:
name: halo2-native-linux-arm64
path: zeroj-verifier-halo2/src/main/resources/native/linux-arm64/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/linux-arm64/

- name: Download halo2 native (macos-arm64)
uses: actions/download-artifact@v4
with:
name: halo2-native-macos-arm64
path: zeroj-verifier-halo2/src/main/resources/native/macos-arm64/
path: incubator/zeroj-verifier-halo2/src/main/resources/native/macos-arm64/

- name: Verify native libraries are in place
run: |
echo "=== gnark native libraries ==="
find zeroj-prover-gnark/src/main/resources/native -type f
echo "=== halo2 native libraries ==="
find zeroj-verifier-halo2/src/main/resources/native -type f
find incubator/zeroj-verifier-halo2/src/main/resources/native -type f

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ zeroj-test-vectors/scripts/build-plonk/
*.r1cs
*.sym
*.ptau
!zeroj-crypto/src/test/resources/test-circuits/plonk-multiplier/pot8_final.ptau

### Node.js (circom tooling) ###
node_modules/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.bloxbean.cardano.zeroj.api;

import java.math.BigInteger;
import java.util.Map;

/**
* A single R1CS (Rank-1 Constraint System) constraint of the form
* {@code (A · w) × (B · w) = (C · w)}, where {@code A}, {@code B}, and
* {@code C} are sparse vectors mapping wire indices to field coefficients
* and {@code w} is the witness vector.
*/
public record R1CSConstraint(
Map<Integer, BigInteger> a,
Map<Integer, BigInteger> b,
Map<Integer, BigInteger> c
) {}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.bloxbean.cardano.zeroj.circuit.r1cs;

import com.bloxbean.cardano.zeroj.api.R1CSConstraint;
import com.bloxbean.cardano.zeroj.circuit.*;

import java.math.BigInteger;
Expand Down Expand Up @@ -38,7 +39,7 @@ public static R1CSConstraintSystem compile(ConstraintGraph graph, FieldConfig co
exprMap.put(v.id(), Map.of(v.id(), BigInteger.ONE));
}

List<R1CSConstraintSystem.R1CSConstraint> constraints = new ArrayList<>();
List<R1CSConstraint> constraints = new ArrayList<>();

for (var gate : graph.gates()) {
switch (gate) {
Expand Down Expand Up @@ -73,7 +74,7 @@ public static R1CSConstraintSystem compile(ConstraintGraph graph, FieldConfig co
var a = getExpr(exprMap, left.id());
var b = getExpr(exprMap, right.id());
var c = Map.of(out.id(), BigInteger.ONE);
constraints.add(new R1CSConstraintSystem.R1CSConstraint(a, b, c));
constraints.add(new R1CSConstraint(a, b, c));
// Multiplication output is a new base variable
exprMap.put(out.id(), Map.of(out.id(), BigInteger.ONE));
}
Expand All @@ -84,7 +85,7 @@ public static R1CSConstraintSystem compile(ConstraintGraph graph, FieldConfig co
var rightExpr = getExpr(exprMap, right.id());
var diff = subExprs(leftExpr, rightExpr, p);
if (!diff.isEmpty()) {
constraints.add(new R1CSConstraintSystem.R1CSConstraint(
constraints.add(new R1CSConstraint(
diff,
Map.of(graph.oneWire().id(), BigInteger.ONE),
Map.of() // = 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.bloxbean.cardano.zeroj.circuit.r1cs;

import com.bloxbean.cardano.zeroj.api.R1CSConstraint;
import com.bloxbean.cardano.zeroj.circuit.FieldConfig;

import java.math.BigInteger;
import java.util.List;
import java.util.Map;

/**
* A compiled R1CS (Rank-1 Constraint System) for Groth16 proving.
Expand All @@ -19,19 +19,6 @@ public record R1CSConstraintSystem(
int numPrivateInputs,
List<R1CSConstraint> constraints
) {
/**
* A single R1CS constraint: (A · w) × (B · w) = (C · w).
*
* @param a sparse vector: wire index → coefficient
* @param b sparse vector
* @param c sparse vector
*/
public record R1CSConstraint(
Map<Integer, BigInteger> a,
Map<Integer, BigInteger> b,
Map<Integer, BigInteger> c
) {}

public BigInteger prime() { return fieldConfig.prime(); }
public int numConstraints() { return constraints.size(); }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.bloxbean.cardano.zeroj.crypto.groth16;

import com.bloxbean.cardano.zeroj.api.R1CSConstraint;
import com.bloxbean.cardano.zeroj.crypto.ec.JacobianG1BN254;
import com.bloxbean.cardano.zeroj.crypto.ec.JacobianG1BN254.AffineG1;
import com.bloxbean.cardano.zeroj.crypto.ec.JacobianG2BN254;
Expand All @@ -10,6 +11,7 @@

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.List;
import java.util.Map;

/**
Expand Down Expand Up @@ -47,7 +49,7 @@ private Groth16Prover() {}
public static Groth16Proof prove(
Groth16ProvingKey pk,
BigInteger[] witness,
R1CSConstraint[] constraints,
List<R1CSConstraint> constraints,
int numWires) {
// Domain size = length of H points array in proving key
int domainSize = pk.pointsH().length;
Expand All @@ -57,7 +59,7 @@ public static Groth16Proof prove(
public static Groth16Proof prove(
Groth16ProvingKey pk,
BigInteger[] witness,
R1CSConstraint[] constraints,
List<R1CSConstraint> constraints,
int numWires,
int domainSize) {

Expand All @@ -82,7 +84,7 @@ public static Groth16Proof prove(
if (!pk.deltaG2().isOnCurve())
throw new IllegalArgumentException("Proving key deltaG2 is not on curve");

int numConstraints = constraints.length;
int numConstraints = constraints.size();

// Note: witness validation is available via validateWitness() for R1CS-standard constraints.
// Not called here because .zkey Section 4 constraints use a different encoding
Expand All @@ -102,8 +104,8 @@ public static Groth16Proof prove(
/** Prove without blinding (r=0, s=0) — for debugging only. */
static Groth16Proof proveUnblinded(
Groth16ProvingKey pk, BigInteger[] witness,
R1CSConstraint[] constraints, int numWires, int domainSize) {
BigInteger[] hCoeffs = computeH(constraints, witness, constraints.length, domainSize);
List<R1CSConstraint> constraints, int numWires, int domainSize) {
BigInteger[] hCoeffs = computeH(constraints, witness, constraints.size(), domainSize);
BigInteger r = BigInteger.ZERO;
BigInteger s = BigInteger.ZERO;
return proveInternal(pk, witness, hCoeffs, r, s);
Expand Down Expand Up @@ -146,7 +148,7 @@ private static Groth16Proof proveInternal(
* <p>The coset generator is omega_{2n} = the primitive (2*domainSize)-th root of unity,
* which equals the square root of the domain's omega_n.</p>
*/
static BigInteger[] computeH(R1CSConstraint[] constraints, BigInteger[] witness,
static BigInteger[] computeH(List<R1CSConstraint> constraints, BigInteger[] witness,
int numConstraints, int domainSize) {
BigInteger mod = MontFr254.modulus();
if (domainSize < 2) domainSize = 2;
Expand All @@ -156,10 +158,12 @@ static BigInteger[] computeH(R1CSConstraint[] constraints, BigInteger[] witness,
MontFr254[] aEval = new MontFr254[domainSize];
MontFr254[] bEval = new MontFr254[domainSize];

int constraintCount = constraints.size();
for (int i = 0; i < domainSize; i++) {
if (i < numConstraints && i < constraints.length) {
aEval[i] = evalLinComb(constraints[i].a(), witness, mod);
bEval[i] = evalLinComb(constraints[i].b(), witness, mod);
if (i < numConstraints && i < constraintCount) {
R1CSConstraint constraint = constraints.get(i);
aEval[i] = evalLinComb(constraint.a(), witness, mod);
bEval[i] = evalLinComb(constraint.b(), witness, mod);
} else {
aEval[i] = MontFr254.ZERO;
bEval[i] = MontFr254.ZERO;
Expand Down Expand Up @@ -389,10 +393,10 @@ private static BigInteger randomScalar(SecureRandom rng) {
* <p>Use this with standard R1CS constraints (from .r1cs files), NOT with .zkey
* Section 4 constraints which use a different encoding where C is implicit.</p>
*/
public static void validateWitness(R1CSConstraint[] constraints, BigInteger[] witness, int numConstraints) {
public static void validateWitness(List<R1CSConstraint> constraints, BigInteger[] witness, int numConstraints) {
BigInteger mod = MontFr254.modulus();
for (int i = 0; i < numConstraints; i++) {
var c = constraints[i];
var c = constraints.get(i);
// Empty constraints (0*0=0) are trivially satisfied — skip
if (c.a().isEmpty() && c.b().isEmpty() && c.c().isEmpty()) continue;

Expand Down Expand Up @@ -423,10 +427,4 @@ private static BigInteger evalLCBigInt(Map<Integer, BigInteger> lc, BigInteger[]
return sum.mod(mod);
}

/** R1CS constraint: A · w × B · w = C · w */
public record R1CSConstraint(
Map<Integer, BigInteger> a,
Map<Integer, BigInteger> b,
Map<Integer, BigInteger> c
) {}
}
Loading
Loading