Skip to content

Commit aa0a418

Browse files
author
Kunming Jiang
committed
Conversion to ceno ExtensionField and Transcript
1 parent 5e24594 commit aa0a418

21 files changed

+1674
-2096
lines changed

circ_blocks/Cargo.lock

Lines changed: 319 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

circ_blocks/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ paste = "1"
5959
im = "15"
6060
once_cell = "1"
6161
regex = "1"
62+
ff_ext = { path = "../../ceno/ff_ext" }
63+
goldilocks = { git = "https://github.com/scroll-tech/ceno-Goldilocks" }
6264

6365
[dev-dependencies]
6466
quickcheck = "1"

circ_blocks/examples/zxc.rs

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ use circ::target::r1cs::wit_comp::StagedWitCompEvaluator;
1313
use circ::target::r1cs::ProverData;
1414
use circ::target::r1cs::{Lc, VarType};
1515
use core::cmp::min;
16-
use libspartan::scalar::{ScalarExt2, SpartanExtensionField};
16+
use ff_ext::ExtensionField;
17+
use libspartan::{
18+
bytes::{to_bytes},
19+
transcript::Transcript,
20+
};
21+
use goldilocks::GoldilocksExt2;
1722
use rug::Integer;
1823

1924
use std::fs::{create_dir_all, File};
@@ -31,7 +36,6 @@ use std::path::PathBuf;
3136
use libspartan::{
3237
instance::Instance, Assignment, InputsAssignment, MemsAssignment, VarsAssignment, SNARK,
3338
};
34-
use merlin::Transcript;
3539
use serde::{Deserialize, Serialize};
3640
use std::time::*;
3741

@@ -361,7 +365,7 @@ impl CompileTimeKnowledge {
361365
}
362366

363367
#[derive(Serialize, Deserialize)]
364-
struct RunTimeKnowledge<S: SpartanExtensionField + Send + Sync> {
368+
struct RunTimeKnowledge<E: ExtensionField + Send + Sync> {
365369
block_max_num_proofs: usize,
366370
block_num_proofs: Vec<usize>,
367371
consis_num_proofs: usize,
@@ -370,14 +374,14 @@ struct RunTimeKnowledge<S: SpartanExtensionField + Send + Sync> {
370374
total_num_phy_mem_accesses: usize,
371375
total_num_vir_mem_accesses: usize,
372376

373-
block_vars_matrix: Vec<Vec<VarsAssignment<S>>>,
374-
exec_inputs: Vec<InputsAssignment<S>>,
377+
block_vars_matrix: Vec<Vec<VarsAssignment<E>>>,
378+
exec_inputs: Vec<InputsAssignment<E>>,
375379
// Initial memory state, in (addr, val, ls = STORE, ts = 0) pair, sorted by appearance in program input (the same as address order)
376-
init_phy_mems_list: Vec<MemsAssignment<S>>,
377-
init_vir_mems_list: Vec<MemsAssignment<S>>,
378-
addr_phy_mems_list: Vec<MemsAssignment<S>>,
379-
addr_vir_mems_list: Vec<MemsAssignment<S>>,
380-
addr_ts_bits_list: Vec<MemsAssignment<S>>,
380+
init_phy_mems_list: Vec<MemsAssignment<E>>,
381+
init_vir_mems_list: Vec<MemsAssignment<E>>,
382+
addr_phy_mems_list: Vec<MemsAssignment<E>>,
383+
addr_vir_mems_list: Vec<MemsAssignment<E>>,
384+
addr_ts_bits_list: Vec<MemsAssignment<E>>,
381385

382386
input: Vec<[u8; 32]>,
383387
input_stack: Vec<[u8; 32]>,
@@ -386,7 +390,7 @@ struct RunTimeKnowledge<S: SpartanExtensionField + Send + Sync> {
386390
output_exec_num: usize,
387391
}
388392

389-
impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
393+
impl<E: ExtensionField + Send + Sync> RunTimeKnowledge<E> {
390394
fn serialize_to_file(
391395
&self,
392396
benchmark_name: String,
@@ -455,7 +459,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
455459
for exec in block {
456460
writeln!(&mut f, "EXEC {}", exec_counter)?;
457461
for assg in &exec.assignment {
458-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
462+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
459463
}
460464
writeln!(&mut f)?;
461465
exec_counter += 1;
@@ -467,7 +471,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
467471
for exec in &self.exec_inputs {
468472
writeln!(&mut f, "EXEC {}", exec_counter)?;
469473
for assg in &exec.assignment {
470-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
474+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
471475
}
472476
writeln!(&mut f)?;
473477
exec_counter += 1;
@@ -477,7 +481,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
477481
for addr in &self.init_phy_mems_list {
478482
writeln!(&mut f, "ACCESS {}", addr_counter)?;
479483
for assg in &addr.assignment {
480-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
484+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
481485
}
482486
writeln!(&mut f)?;
483487
addr_counter += 1;
@@ -487,7 +491,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
487491
for addr in &self.init_vir_mems_list {
488492
writeln!(&mut f, "ACCESS {}", addr_counter)?;
489493
for assg in &addr.assignment {
490-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
494+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
491495
}
492496
writeln!(&mut f)?;
493497
addr_counter += 1;
@@ -497,7 +501,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
497501
for addr in &self.addr_phy_mems_list {
498502
writeln!(&mut f, "ACCESS {}", addr_counter)?;
499503
for assg in &addr.assignment {
500-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
504+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
501505
}
502506
writeln!(&mut f)?;
503507
addr_counter += 1;
@@ -507,7 +511,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
507511
for addr in &self.addr_vir_mems_list {
508512
writeln!(&mut f, "ACCESS {}", addr_counter)?;
509513
for assg in &addr.assignment {
510-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
514+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
511515
}
512516
writeln!(&mut f)?;
513517
addr_counter += 1;
@@ -517,7 +521,7 @@ impl<S: SpartanExtensionField + Send + Sync> RunTimeKnowledge<S> {
517521
for addr in &self.addr_ts_bits_list {
518522
writeln!(&mut f, "ACCESS {}", addr_counter)?;
519523
for assg in &addr.assignment {
520-
write!(&mut f, "{} ", bytes_to_integer(&assg.to_bytes()))?;
524+
write!(&mut f, "{} ", bytes_to_integer(&to_bytes(*assg)))?;
521525
}
522526
writeln!(&mut f)?;
523527
addr_counter += 1;
@@ -850,7 +854,7 @@ fn get_compile_time_knowledge<const VERBOSE: bool>(
850854
// --
851855
// Generate witnesses and others
852856
// --
853-
fn get_run_time_knowledge<const VERBOSE: bool, S: SpartanExtensionField + Send + Sync>(
857+
fn get_run_time_knowledge<const VERBOSE: bool, E: ExtensionField + Send + Sync>(
854858
path: PathBuf,
855859
options: &Options,
856860
entry_regs: Vec<Integer>,
@@ -863,7 +867,7 @@ fn get_run_time_knowledge<const VERBOSE: bool, S: SpartanExtensionField + Send +
863867
prover_data_list: Vec<ProverData>,
864868
total_num_init_phy_mem_accesses: usize,
865869
total_num_init_vir_mem_accesses: usize,
866-
) -> RunTimeKnowledge<S> {
870+
) -> RunTimeKnowledge<E> {
867871
let num_blocks = ctk.block_num_instances;
868872
let num_input_unpadded = ctk.num_inputs_unpadded;
869873
let io_width = 2 * num_input_unpadded;
@@ -1285,9 +1289,9 @@ fn get_run_time_knowledge<const VERBOSE: bool, S: SpartanExtensionField + Send +
12851289
}
12861290
}
12871291

1288-
fn run_spartan_proof<S: SpartanExtensionField + Send + Sync>(
1292+
fn run_spartan_proof<E: ExtensionField + Send + Sync>(
12891293
ctk: CompileTimeKnowledge,
1290-
rtk: RunTimeKnowledge<S>,
1294+
rtk: RunTimeKnowledge<E>,
12911295
) {
12921296
// --
12931297
// INSTANCE PREPROCESSING
@@ -1329,7 +1333,7 @@ fn run_spartan_proof<S: SpartanExtensionField + Send + Sync>(
13291333
&rtk.block_num_proofs,
13301334
);
13311335
// block_inst is used by commitment. Every block has different number of variables
1332-
let (_, _, _, block_inst_for_commit) = Instance::<S>::gen_block_inst::<true, true>(
1336+
let (_, _, _, block_inst_for_commit) = Instance::<E>::gen_block_inst::<true, true>(
13331337
block_num_instances_bound,
13341338
num_vars,
13351339
&ctk.args,
@@ -1600,7 +1604,7 @@ fn main() {
16001604
// --
16011605
// Generate Witnesses
16021606
// --
1603-
let rtk = get_run_time_knowledge::<false, ScalarExt2>(
1607+
let rtk = get_run_time_knowledge::<false, GoldilocksExt2>(
16041608
path.clone(),
16051609
&options,
16061610
entry_regs,
@@ -1634,4 +1638,4 @@ fn main() {
16341638

16351639
println!("Compiler time: {}ms", compiler_time.as_millis());
16361640
println!("\n--\nWitness time: {}ms", witness_time.as_millis());
1637-
}
1641+
}

spartan_parallel/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ colored = { version = "2", default-features = false, optional = true }
3030
flate2 = { version = "1" }
3131
goldilocks = { git = "https://github.com/scroll-tech/ceno-Goldilocks" }
3232
ff = "0.13.0"
33+
ff_ext = { path = "../../ceno/ff_ext" }
34+
transcript = { path = "../../ceno/transcript" }
3335

3436
[dev-dependencies]
3537
criterion = "0.5"

spartan_parallel/examples/interface.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
use std::io::{BufRead, Read};
55
use std::{default, env};
66
use std::{fs::File, io::BufReader};
7-
8-
use libspartan::scalar::{ScalarExt2, SpartanExtensionField};
9-
use libspartan::{instance::Instance, InputsAssignment, MemsAssignment, VarsAssignment, SNARK};
10-
use merlin::Transcript;
7+
use ff_ext::ExtensionField;
8+
use goldilocks::GoldilocksExt2;
9+
use libspartan::{instance::Instance, InputsAssignment, MemsAssignment, VarsAssignment, SNARK, transcript::Transcript};
1110
use serde::{Deserialize, Serialize};
1211
use std::time::*;
1312

@@ -59,7 +58,7 @@ impl CompileTimeKnowledge {
5958

6059
// Everything provided by the prover
6160
#[derive(Serialize, Deserialize)]
62-
struct RunTimeKnowledge<S: SpartanExtensionField> {
61+
struct RunTimeKnowledge<E: ExtensionField> {
6362
block_max_num_proofs: usize,
6463
block_num_proofs: Vec<usize>,
6564
consis_num_proofs: usize,
@@ -68,13 +67,13 @@ struct RunTimeKnowledge<S: SpartanExtensionField> {
6867
total_num_phy_mem_accesses: usize,
6968
total_num_vir_mem_accesses: usize,
7069

71-
block_vars_matrix: Vec<Vec<VarsAssignment<S>>>,
72-
exec_inputs: Vec<InputsAssignment<S>>,
73-
init_phy_mems_list: Vec<MemsAssignment<S>>,
74-
init_vir_mems_list: Vec<MemsAssignment<S>>,
75-
addr_phy_mems_list: Vec<MemsAssignment<S>>,
76-
addr_vir_mems_list: Vec<MemsAssignment<S>>,
77-
addr_ts_bits_list: Vec<MemsAssignment<S>>,
70+
block_vars_matrix: Vec<Vec<VarsAssignment<E>>>,
71+
exec_inputs: Vec<InputsAssignment<E>>,
72+
init_phy_mems_list: Vec<MemsAssignment<E>>,
73+
init_vir_mems_list: Vec<MemsAssignment<E>>,
74+
addr_phy_mems_list: Vec<MemsAssignment<E>>,
75+
addr_vir_mems_list: Vec<MemsAssignment<E>>,
76+
addr_ts_bits_list: Vec<MemsAssignment<E>>,
7877

7978
input: Vec<[u8; 32]>,
8079
input_stack: Vec<[u8; 32]>,
@@ -83,8 +82,8 @@ struct RunTimeKnowledge<S: SpartanExtensionField> {
8382
output_exec_num: usize,
8483
}
8584

86-
impl<S: SpartanExtensionField + for<'de> serde::de::Deserialize<'de>> RunTimeKnowledge<S> {
87-
fn deserialize_from_file(benchmark_name: String) -> RunTimeKnowledge<S> {
85+
impl<E: ExtensionField + for<'de> serde::de::Deserialize<'de>> RunTimeKnowledge<E> {
86+
fn deserialize_from_file(benchmark_name: String) -> RunTimeKnowledge<E> {
8887
// Input can be provided through multiple files, use i to determine the next file label
8988
let mut i = 0;
9089
let mut file_name = format!("../zok_tests/inputs/{benchmark_name}_bin_{i}.rtk");
@@ -105,7 +104,7 @@ fn main() {
105104
// let ctk = CompileTimeKnowledge::read_from_file(benchmark_name.to_string()).unwrap();
106105
let ctk = CompileTimeKnowledge::deserialize_from_file(benchmark_name.to_string());
107106
// let rtk = RunTimeKnowledge::read_from_file(benchmark_name.to_string()).unwrap();
108-
let rtk: RunTimeKnowledge<ScalarExt2> =
107+
let rtk: RunTimeKnowledge<GoldilocksExt2> =
109108
RunTimeKnowledge::deserialize_from_file(benchmark_name.to_string());
110109

111110
// --
@@ -148,7 +147,7 @@ fn main() {
148147
&rtk.block_num_proofs,
149148
);
150149
// block_inst is used by commitment. Every block has different number of variables
151-
let (_, _, _, block_inst_for_commit) = Instance::<ScalarExt2>::gen_block_inst::<true, true>(
150+
let (_, _, _, block_inst_for_commit) = Instance::<GoldilocksExt2>::gen_block_inst::<true, true>(
152151
block_num_instances_bound,
153152
num_vars,
154153
&ctk.args,

spartan_parallel/src/bytes.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use ff_ext::ExtensionField;
2+
use subtle::{Choice, CtOption};
3+
4+
/// Attempts to convert a little-endian byte representation of
5+
/// a field element into an `ExtensionField`, failing if the input is not canonical.
6+
pub fn from_bytes<E: ExtensionField>(bytes: &[u8; 32]) -> CtOption<E> {
7+
let mut padded = [0u8; 64];
8+
padded[..32].copy_from_slice(bytes);
9+
10+
CtOption::new(
11+
E::from_uniform_bytes(&padded),
12+
Choice::from(1u8),
13+
)
14+
}
15+
16+
/// Converts an element of `ExtensionField` into a byte representation in
17+
/// little-endian byte order.
18+
pub fn to_bytes<E: ExtensionField>(num: E) -> [u8; 32] {
19+
let mut res = [0; 32];
20+
let els = num.to_canonical_u64_vec();
21+
res[..8].copy_from_slice(&els[0].to_le_bytes());
22+
res[8..16].copy_from_slice(&els[1].to_le_bytes());
23+
res
24+
}
25+
26+
/// Converts a 512-bit little endian integer into
27+
/// an `ExtensionField` element by reducing by the modulus.
28+
pub fn from_bytes_wide<E: ExtensionField>(bytes: &[u8; 64]) -> E {
29+
E::from_uniform_bytes(bytes).into()
30+
}

0 commit comments

Comments
 (0)