Skip to content

Commit 2ebd0a1

Browse files
authored
Fix spartan (and include its tests in CI) (#184)
Spartan bit-rotted because CI was misconfigured.
1 parent d0b529b commit 2ebd0a1

File tree

5 files changed

+46
-67
lines changed

5 files changed

+46
-67
lines changed

driver.py

+2-15
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ def check(features):
4444
cmd = ["cargo", "check", "--tests", "--examples", "--benches", "--bins"]
4545
if features:
4646
cmd = cmd + ["--features"] + [",".join(features)]
47-
if "ristretto255" in features:
48-
cmd = cmd + ["--no-default-features"]
4947
log_run_check(cmd)
5048

5149

@@ -82,8 +80,6 @@ def build(features):
8280

8381
if features:
8482
cmd = cmd + ["--features"] + [",".join(features)]
85-
if "ristretto255" in features:
86-
cmd = cmd + ["--no-default-features"]
8783

8884
log_run_check(cmd)
8985

@@ -114,9 +110,6 @@ def test(features, extra_args):
114110
if features:
115111
test_cmd += ["--features"] + [",".join(features)]
116112
test_cmd_release += ["--features"] + [",".join(features)]
117-
if "ristretto255" in features:
118-
test_cmd += ["--no-default-features"]
119-
test_cmd_release += ["--no-default-features"]
120113
if len(extra_args) > 0:
121114
test_cmd += [a for a in extra_args if a != "--"]
122115
test_cmd_release += [a for a in extra_args if a != "--"]
@@ -135,7 +128,7 @@ def test(features, extra_args):
135128
if "lp" in features:
136129
log_run_check(["./scripts/test_zok_to_ilp.zsh"])
137130
if "r1cs" in features:
138-
if "ristretto255" in features: # spartan field
131+
if "spartan" in features: # spartan field
139132
log_run_check(["./scripts/spartan_zok_test.zsh"])
140133
else: # bellman field
141134
log_run_check(["./scripts/zokrates_test.zsh"])
@@ -168,8 +161,6 @@ def benchmark(features):
168161

169162
if features:
170163
cmd = cmd + ["--features"] + [",".join(features)]
171-
if "ristretto255" in features:
172-
cmd = cmd + ["--no-default-features"]
173164
log_run_check(cmd)
174165

175166

@@ -192,17 +183,13 @@ def lint():
192183
cmd = ["cargo", "clippy", "--tests", "--examples", "--benches", "--bins"]
193184
if features:
194185
cmd = cmd + ["--features"] + [",".join(features)]
195-
if "ristretto255" in features:
196-
cmd = cmd + ["--no-default-features"]
197186
log_run_check(cmd)
198187

199188

200189
def flamegraph(features, extra):
201190
cmd = ["cargo", "flamegraph"]
202191
if features:
203192
cmd = cmd + ["--features"] + [",".join(features)]
204-
if "ristretto255" in features:
205-
cmd = cmd + ["--no-default-features"]
206193
cmd += extra
207194
print("running:", " ".join(cmd))
208195
log_run_check(cmd)
@@ -243,7 +230,7 @@ def set_features(features):
243230
features = set()
244231

245232
def verify_feature(f):
246-
if f in cargo_features | {"ristretto255"}:
233+
if f in cargo_features:
247234
return True
248235
return False
249236

scripts/spartan_zok_test.zsh

+11-8
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@ case "$OSTYPE" in
1717
;;
1818
esac
1919

20+
modulus=7237005577332262213973186563042994240857116359379907606001950938285454250989
21+
2022
function r1cs_test {
2123
zpath=$1
22-
measure_time $BIN $zpath r1cs --action count
24+
measure_time $BIN --field-custom-modulus $modulus $zpath r1cs --action count
2325
}
2426

2527
function r1cs_test_count {
2628
zpath=$1
2729
threshold=$2
28-
o=$($BIN $zpath r1cs --action count)
30+
o=$($BIN --field-custom-modulus $modulus $zpath r1cs --action count)
2931
n_constraints=$(echo $o | grep 'Final R1cs size:' | grep -Eo '\b[0-9]+\b')
3032
[[ $n_constraints -lt $threshold ]] || (echo "Got $n_constraints, expected < $threshold" && exit 1)
3133
}
@@ -34,27 +36,29 @@ function r1cs_test_count {
3436
# examples that don't need modulus change
3537
function pf_test {
3638
ex_name=$1
37-
$BIN examples/ZoKrates/pf/$ex_name.zok r1cs --action spartansetup
39+
$BIN --field-custom-modulus $modulus examples/ZoKrates/pf/$ex_name.zok r1cs --action spartan-setup
3840
$ZK_BIN --pin examples/ZoKrates/pf/$ex_name.zok.pin --vin examples/ZoKrates/pf/$ex_name.zok.vin --action spartan
3941
rm -rf P V pi
4042
}
4143

42-
# Test prove workflow with --z-isolate-asserts, given an example name
44+
# Test prove workflow with --zsharp-isolate-asserts, given an example name
4345
function spartan_test_isolate {
4446
ex_name=$1
45-
$BIN --z-isolate-asserts examples/ZoKrates/spartan/$ex_name.zok r1cs --action spartansetup
47+
$BIN --field-custom-modulus $modulus --zsharp-isolate-asserts true examples/ZoKrates/spartan/$ex_name.zok r1cs --action spartan-setup
4648
$ZK_BIN --pin examples/ZoKrates/spartan/$ex_name.zok.pin --vin examples/ZoKrates/spartan/$ex_name.zok.vin --action spartan
4749
rm -rf P V pi
4850
}
4951

5052
# Test prove workflow, given an example name
5153
function spartan_test {
5254
ex_name=$1
53-
$BIN examples/ZoKrates/spartan/$ex_name.zok r1cs --action spartansetup
54-
$ZK_BIN --pin examples/ZoKrates/spartan/$ex_name.zok.pin --vin examples/ZoKrates/spartan/$ex_name.zok.vin --action spartan
55+
$BIN --field-custom-modulus $modulus examples/ZoKrates/spartan/$ex_name.zok r1cs --action spartan-setup
56+
$ZK_BIN --field-custom-modulus $modulus --pin examples/ZoKrates/spartan/$ex_name.zok.pin --vin examples/ZoKrates/spartan/$ex_name.zok.vin --action spartan
5557
rm -rf P V pi
5658
}
5759

60+
spartan_test assert
61+
5862
r1cs_test_count ./examples/ZoKrates/pf/mm4_cond.zok 120
5963
r1cs_test ./third_party/ZoKrates/zokrates_stdlib/stdlib/ecc/edwardsAdd.zok
6064
r1cs_test ./third_party/ZoKrates/zokrates_stdlib/stdlib/ecc/edwardsOnCurve.zok
@@ -70,7 +74,6 @@ r1cs_test ./third_party/ZoKrates/zokrates_stdlib/stdlib/ecc/edwardsScalarMult.zo
7074
r1cs_test ./third_party/ZoKrates/zokrates_stdlib/stdlib/hashes/mimc7/mimc7R20.zok
7175
r1cs_test ./third_party/ZoKrates/zokrates_stdlib/stdlib/hashes/pedersen/512bit.zok
7276

73-
spartan_test assert
7477
spartan_test_isolate isolate_assert
7578
pf_test 3_plus
7679
pf_test xor

scripts/zokrates_test.zsh

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function pf_test_only_pf {
5656
done
5757
}
5858

59-
# Test prove workflow with --z-isolate-asserts, given an example name
59+
# Test prove workflow with --zsharp-isolate-asserts, given an example name
6060
function pf_test_isolate {
6161
for proof_impl in groth16 mirage
6262
do

src/target/r1cs/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ impl R1csFinal {
464464
}
465465

466466
impl ProverData {
467-
/// Check all assertions. Puts in 1 for challenges.
468-
pub fn check_all(&self, values: &HashMap<String, Value>) {
467+
/// Compute an R1CS witness (setting any challenges to 1s)
468+
pub fn extend_r1cs_witness(&self, values: &HashMap<String, Value>) -> HashMap<Var, FieldV> {
469469
// we need to evaluate all R1CS variables
470470
let mut var_values: HashMap<Var, FieldV> = Default::default();
471471
let mut eval = wit_comp::StagedWitCompEvaluator::new(&self.precompute);
@@ -504,7 +504,11 @@ impl ProverData {
504504
}
505505
}
506506
}
507-
self.r1cs.check_all(&var_values);
507+
var_values
508+
}
509+
/// Check all assertions. Puts in 1 for challenges.
510+
pub fn check_all(&self, values: &HashMap<String, Value>) {
511+
self.r1cs.check_all(&self.extend_r1cs_witness(values));
508512
}
509513

510514
/// How many commitments?

src/target/r1cs/spartan.rs

+25-40
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//! Export circ R1cs to Spartan
2-
use crate::target::r1cs::wit_comp::StagedWitCompEvaluator;
32
use crate::target::r1cs::*;
43
use bincode::{deserialize_from, serialize_into};
54
use curve25519_dalek::scalar::Scalar;
@@ -95,31 +94,42 @@ pub fn r1cs_to_spartan(
9594
"\nR1CS has modulus \n{s_mod},\n but Spartan CS expects \n{f_mod}",
9695
);
9796

98-
let values = eval_inputs(inputs_map, prover_data);
97+
let values = prover_data.extend_r1cs_witness(inputs_map);
98+
prover_data.r1cs.check_all(&values);
9999

100100
assert_eq!(values.len(), prover_data.r1cs.vars.len());
101101

102-
for (var, val) in prover_data.r1cs.vars.iter().zip(&values) {
103-
let scalar = val_to_scalar(val);
102+
for var in prover_data.r1cs.vars.iter() {
103+
assert!(matches!(var.ty(), VarType::Inst | VarType::FinalWit));
104+
if let VarType::FinalWit = var.ty() {
105+
// witness
106+
let id = wit.len();
107+
itrans.insert(id, *var);
108+
trans.insert(*var, id);
109+
let val = values.get(var).expect("missing R1CS value");
110+
wit.push(int_to_scalar(&val.i()).to_bytes());
111+
}
112+
}
104113

105-
// input
106-
itrans.insert(inp.len(), *var);
107-
trans.insert(*var, inp.len());
114+
let const_id = wit.len();
115+
116+
for var in prover_data.r1cs.vars.iter() {
117+
assert!(matches!(var.ty(), VarType::Inst | VarType::FinalWit));
108118
if let VarType::Inst = var.ty() {
109-
inp.push(scalar.to_bytes());
110-
} else {
111-
wit.push(scalar.to_bytes());
119+
// input
120+
let id = wit.len() + 1 + inp.len();
121+
itrans.insert(id, *var);
122+
trans.insert(*var, id);
123+
let val = values.get(var).expect("missing R1CS value");
124+
inp.push(int_to_scalar(&val.i()).to_bytes());
112125
}
113126
}
114127

115-
assert_eq!(wit.len() + inp.len(), prover_data.r1cs.vars.len());
116-
117128
let num_vars = wit.len();
118-
let const_id = wit.len();
129+
let num_inputs = inp.len();
130+
assert_eq!(wit.len() + inp.len(), prover_data.r1cs.vars.len());
119131

120132
let assn_witness = VarsAssignment::new(&wit).unwrap();
121-
122-
let num_inputs = inp.len();
123133
let assn_inputs = InputsAssignment::new(&inp).unwrap();
124134

125135
// circuit
@@ -166,31 +176,6 @@ pub fn r1cs_to_spartan(
166176
)
167177
}
168178

169-
fn eval_inputs(inputs_map: &HashMap<String, Value>, prover_data: &ProverData) -> Vec<Value> {
170-
let mut evaluator = StagedWitCompEvaluator::new(&prover_data.precompute);
171-
let mut ffs = Vec::new();
172-
ffs.extend(
173-
evaluator
174-
.eval_stage(inputs_map.clone())
175-
.into_iter()
176-
.cloned(),
177-
);
178-
ffs.extend(
179-
evaluator
180-
.eval_stage(Default::default())
181-
.into_iter()
182-
.cloned(),
183-
);
184-
ffs
185-
}
186-
187-
fn val_to_scalar(v: &Value) -> Scalar {
188-
match v.sort() {
189-
Sort::Field(_) => return int_to_scalar(&v.as_pf().i()),
190-
_ => panic!("Value should be a field"),
191-
};
192-
}
193-
194179
fn int_to_scalar(i: &Integer) -> Scalar {
195180
let mut accumulator = Scalar::zero();
196181
let limb_bits = (std::mem::size_of::<limb_t>() as u64) << 3;

0 commit comments

Comments
 (0)