diff --git a/Cargo.lock b/Cargo.lock index dfbcd4d5b..7524e9d64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,11 +330,9 @@ dependencies = [ "cfg-if", "clap", "criterion", - "ff", "ff_ext", "generic_static", "glob", - "goldilocks", "itertools 0.13.0", "mpcs", "multilinear_extensions", diff --git a/ceno_zkvm/Cargo.toml b/ceno_zkvm/Cargo.toml index 6ea2173a8..9a7b61176 100644 --- a/ceno_zkvm/Cargo.toml +++ b/ceno_zkvm/Cargo.toml @@ -11,8 +11,6 @@ version.workspace = true [dependencies] ark-std.workspace = true -ff.workspace = true -goldilocks.workspace = true rand_chacha.workspace = true rayon.workspace = true serde.workspace = true @@ -27,6 +25,7 @@ sumcheck = { version = "0", path = "../sumcheck" } transcript = { path = "../transcript" } p3-field.workspace = true +p3-goldilocks.workspace = true itertools.workspace = true num-traits.workspace = true paste.workspace = true @@ -51,7 +50,6 @@ cfg-if.workspace = true criterion.workspace = true pprof2.workspace = true proptest.workspace = true -p3-goldilocks.workspace = true [build-dependencies] glob = "0.3" diff --git a/ceno_zkvm/src/circuit_builder.rs b/ceno_zkvm/src/circuit_builder.rs index 5c3e2dc2c..968e84288 100644 --- a/ceno_zkvm/src/circuit_builder.rs +++ b/ceno_zkvm/src/circuit_builder.rs @@ -13,6 +13,7 @@ use crate::{ structs::{ProgramParams, ProvingKey, RAMType, VerifyingKey, WitnessId}, witness::RowMajorMatrix, }; +use p3_field::FieldAlgebra; /// namespace used for annotation, preserve meta info during circuit construction #[derive(Clone, Debug, Default, serde::Serialize)] @@ -275,9 +276,11 @@ impl ConstraintSystem { record: Vec>, ) -> Result<(), ZKVMError> { let rlc_record = self.rlc_chip_record( - std::iter::once(Expression::Constant(E::BaseField::from(rom_type as u64))) - .chain(record.clone()) - .collect(), + std::iter::once(Expression::Constant(E::BaseField::from_canonical_u64( + rom_type as u64, + ))) + .chain(record.clone()) + .collect(), ); assert_eq!( rlc_record.degree(), diff --git a/ceno_zkvm/src/expression/monomial.rs b/ceno_zkvm/src/expression/monomial.rs index 59c3e009b..1f508cb48 100644 --- a/ceno_zkvm/src/expression/monomial.rs +++ b/ceno_zkvm/src/expression/monomial.rs @@ -3,6 +3,7 @@ use itertools::{Itertools, chain, iproduct}; use super::Expression; use Expression::*; +use ff_ext::FieldInto; use std::iter::Sum; impl Expression { @@ -98,7 +99,7 @@ mod tests { let x = || WitIn(0); let y = || WitIn(1); let z = || WitIn(2); - let n = || Constant(104.into()); + let n = || Constant(104u64.into_f()); let m = || Constant(-F::from_canonical_u64(599)); let r = || Challenge(0, 1, E::ONE, E::ZERO); diff --git a/ceno_zkvm/src/gadgets/is_lt.rs b/ceno_zkvm/src/gadgets/is_lt.rs index 2585c7831..c323d7d3b 100644 --- a/ceno_zkvm/src/gadgets/is_lt.rs +++ b/ceno_zkvm/src/gadgets/is_lt.rs @@ -15,6 +15,7 @@ use crate::{ utils::i64_to_base, witness::LkMultiplicity, }; +use ff_ext::FieldInto; use super::SignedExtendConfig; @@ -276,7 +277,7 @@ impl InnerLtConfig { is_lt: bool, ) -> Result<(), ZKVMError> { let range_offset: F = if is_lt { - Self::range(self.max_num_u16_limbs).into() + Self::range(self.max_num_u16_limbs).into_f() } else { F::ZERO }; diff --git a/ceno_zkvm/src/gadgets/is_zero.rs b/ceno_zkvm/src/gadgets/is_zero.rs index 024ebf1bd..7b1348612 100644 --- a/ceno_zkvm/src/gadgets/is_zero.rs +++ b/ceno_zkvm/src/gadgets/is_zero.rs @@ -1,5 +1,4 @@ -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, SmallField}; use crate::{ circuit_builder::CircuitBuilder, @@ -65,10 +64,10 @@ impl IsZeroConfig { instance: &mut [F], x: F, ) -> Result<(), ZKVMError> { - let (is_zero, inverse) = if x.is_zero_vartime() { + let (is_zero, inverse) = if x.is_zero() { (F::ONE, F::ZERO) } else { - (F::ZERO, x.invert().expect("not zero")) + (F::ZERO, x.try_inverse().expect("not zero")) }; if let Some(wit) = self.is_zero { diff --git a/ceno_zkvm/src/gadgets/signed_ext.rs b/ceno_zkvm/src/gadgets/signed_ext.rs index 0ee17208c..3f6be380c 100644 --- a/ceno_zkvm/src/gadgets/signed_ext.rs +++ b/ceno_zkvm/src/gadgets/signed_ext.rs @@ -6,7 +6,8 @@ use crate::{ set_val, witness::LkMultiplicity, }; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; +use p3_field::FieldAlgebra; use std::marker::PhantomData; /// Extract the most significant bit from an expression previously constrained @@ -102,7 +103,7 @@ impl SignedExtendConfig { }; assert_ux(lk_multiplicity, 2 * val - (msb << self.n_bits)); - set_val!(instance, self.msb, E::BaseField::from(msb)); + set_val!(instance, self.msb, E::BaseField::from_canonical_u64(msb)); Ok(()) } diff --git a/ceno_zkvm/src/instructions/riscv/arith.rs b/ceno_zkvm/src/instructions/riscv/arith.rs index f6205130a..66e929a6e 100644 --- a/ceno_zkvm/src/instructions/riscv/arith.rs +++ b/ceno_zkvm/src/instructions/riscv/arith.rs @@ -131,7 +131,7 @@ impl Instruction for ArithInstruction Instruction for AddiInstruction { #[cfg(test)] mod test { use ceno_emul::{Change, InsnKind, PC_STEP_SIZE, StepRecord, encode_rv32}; - use goldilocks::GoldilocksExt2; + use ff_ext::GoldilocksExt2; use crate::{ circuit_builder::{CircuitBuilder, ConstraintSystem}, diff --git a/ceno_zkvm/src/instructions/riscv/b_insn.rs b/ceno_zkvm/src/instructions/riscv/b_insn.rs index 646e9bd05..a4ae7ac92 100644 --- a/ceno_zkvm/src/instructions/riscv/b_insn.rs +++ b/ceno_zkvm/src/instructions/riscv/b_insn.rs @@ -13,6 +13,7 @@ use crate::{ utils::i64_to_base, witness::LkMultiplicity, }; +use ff_ext::FieldInto; // Opcode: 1100011 // Funct3: diff --git a/ceno_zkvm/src/instructions/riscv/branch/branch_circuit.rs b/ceno_zkvm/src/instructions/riscv/branch/branch_circuit.rs index efe38342c..6f0e3aef1 100644 --- a/ceno_zkvm/src/instructions/riscv/branch/branch_circuit.rs +++ b/ceno_zkvm/src/instructions/riscv/branch/branch_circuit.rs @@ -19,6 +19,7 @@ use crate::{ }, witness::LkMultiplicity, }; +pub use p3_field::FieldAlgebra; pub struct BranchCircuit(PhantomData<(E, I)>); @@ -150,8 +151,8 @@ impl Instruction for BranchCircuit { set_val!(instance, config.rhs_ne_byte, rhs_ne_byte); set_val!(instance, config.byte_diff_inv, { if flag { - (lhs_ne_byte - rhs_ne_byte).invert().unwrap() + (lhs_ne_byte - rhs_ne_byte).inverse() } else { F::ONE } diff --git a/ceno_zkvm/src/instructions/riscv/div.rs b/ceno_zkvm/src/instructions/riscv/div.rs index daa7bc000..fb388c94a 100644 --- a/ceno_zkvm/src/instructions/riscv/div.rs +++ b/ceno_zkvm/src/instructions/riscv/div.rs @@ -63,8 +63,8 @@ //! booleans is equal to 1. use ceno_emul::{InsnKind, StepRecord}; -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, FieldInto, SmallField}; +use p3_goldilocks::Goldilocks; use super::{ RIVInstruction, @@ -149,7 +149,7 @@ impl Instruction for ArithInstruction::TOTAL_BITS, u32::BITS as usize); - assert_eq!(E::BaseField::MODULUS_U64, goldilocks::MODULUS); + assert_eq!(E::BaseField::MODULUS_U64, Goldilocks::MODULUS_U64); // 32-bit value from rs1 let dividend = UInt::new_unchecked(|| "dividend", cb)?; @@ -388,13 +388,13 @@ impl Instruction for ArithInstruction Instruction for ArithInstruction(PhantomData<(E, I)>); diff --git a/ceno_zkvm/src/instructions/riscv/dummy/dummy_ecall.rs b/ceno_zkvm/src/instructions/riscv/dummy/dummy_ecall.rs index cd3156387..b1b6fc995 100644 --- a/ceno_zkvm/src/instructions/riscv/dummy/dummy_ecall.rs +++ b/ceno_zkvm/src/instructions/riscv/dummy/dummy_ecall.rs @@ -17,6 +17,7 @@ use crate::{ set_val, witness::LkMultiplicity, }; +use ff_ext::FieldInto; trait EcallSpec { const NAME: &'static str; diff --git a/ceno_zkvm/src/instructions/riscv/dummy/test.rs b/ceno_zkvm/src/instructions/riscv/dummy/test.rs index 199d8a3a8..d61d67b5f 100644 --- a/ceno_zkvm/src/instructions/riscv/dummy/test.rs +++ b/ceno_zkvm/src/instructions/riscv/dummy/test.rs @@ -1,6 +1,6 @@ use ceno_emul::{Change, InsnKind, StepRecord, encode_rv32}; use dummy_ecall::KeccakSpec; -use goldilocks::GoldilocksExt2; +use ff_ext::GoldilocksExt2; use super::*; use crate::{ diff --git a/ceno_zkvm/src/instructions/riscv/ecall/halt.rs b/ceno_zkvm/src/instructions/riscv/ecall/halt.rs index d3d0d90a7..a0d67cc59 100644 --- a/ceno_zkvm/src/instructions/riscv/ecall/halt.rs +++ b/ceno_zkvm/src/instructions/riscv/ecall/halt.rs @@ -15,7 +15,8 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::{StepRecord, Tracer}; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; +use p3_field::FieldAlgebra; use std::marker::PhantomData; pub struct HaltConfig { @@ -50,7 +51,7 @@ impl Instruction for HaltInstruction { // read exit_code from arg0 (X10 register) let (_, lt_x10_cfg) = cb.register_read( || "read x10", - E::BaseField::from(ceno_emul::Platform::reg_arg0() as u64), + E::BaseField::from_canonical_u64(ceno_emul::Platform::reg_arg0() as u64), prev_x10_ts.expr(), ecall_cfg.ts.expr() + Tracer::SUBCYCLE_RS2, exit_code, diff --git a/ceno_zkvm/src/instructions/riscv/ecall_insn.rs b/ceno_zkvm/src/instructions/riscv/ecall_insn.rs index 8de7e02c8..99bcb4ced 100644 --- a/ceno_zkvm/src/instructions/riscv/ecall_insn.rs +++ b/ceno_zkvm/src/instructions/riscv/ecall_insn.rs @@ -11,7 +11,8 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::{InsnKind::ECALL, PC_STEP_SIZE, Platform, StepRecord, Tracer}; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; +use p3_field::FieldAlgebra; pub struct EcallInstructionConfig { pub pc: WitIn, @@ -50,7 +51,7 @@ impl EcallInstructionConfig { // read syscall_id from x5 and write return value to x5 let (_, lt_x5_cfg) = cb.register_write( || "write x5", - E::BaseField::from(Platform::reg_ecall() as u64), + E::BaseField::from_canonical_u64(Platform::reg_ecall() as u64), prev_x5_ts.expr(), ts.expr() + Tracer::SUBCYCLE_RS1, syscall_id.clone(), diff --git a/ceno_zkvm/src/instructions/riscv/insn_base.rs b/ceno_zkvm/src/instructions/riscv/insn_base.rs index 057a27bb5..a862d643a 100644 --- a/ceno_zkvm/src/instructions/riscv/insn_base.rs +++ b/ceno_zkvm/src/instructions/riscv/insn_base.rs @@ -1,8 +1,7 @@ use ceno_emul::{Cycle, StepRecord, Word, WriteOp}; -use ff::Field; -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, FieldInto, SmallField}; use itertools::Itertools; +use p3_field::{Field, FieldAlgebra}; use super::constants::{PC_STEP_SIZE, UINT_LIMBS, UInt}; use crate::{ @@ -437,9 +436,8 @@ impl MemAddr { .sum(); // Range check the middle bits, that is the low limb excluding the low bits. - let shift_right = E::BaseField::from(1 << Self::N_LOW_BITS) - .invert() - .unwrap() + let shift_right = E::BaseField::from_canonical_u64(1 << Self::N_LOW_BITS) + .inverse() .expr(); let mid_u14 = (&limbs[0] - low_sum) * shift_right; cb.assert_ux::<_, _, 14>(|| "mid_u14", mid_u14)?; @@ -486,8 +484,9 @@ impl MemAddr { #[cfg(test)] mod test { - use goldilocks::{Goldilocks as F, GoldilocksExt2 as E}; + use ff_ext::GoldilocksExt2 as E; use itertools::Itertools; + use p3_goldilocks::Goldilocks as F; use crate::{ ROMType, diff --git a/ceno_zkvm/src/instructions/riscv/jump/jalr.rs b/ceno_zkvm/src/instructions/riscv/jump/jalr.rs index cc556c36b..b6bca9190 100644 --- a/ceno_zkvm/src/instructions/riscv/jump/jalr.rs +++ b/ceno_zkvm/src/instructions/riscv/jump/jalr.rs @@ -1,6 +1,5 @@ use std::marker::PhantomData; -use ff::Field; use ff_ext::ExtensionField; use crate::{ @@ -18,6 +17,8 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::{InsnKind, PC_STEP_SIZE}; +use ff_ext::FieldInto; +use p3_field::FieldAlgebra; pub struct JalrConfig { pub i_insn: IInstructionConfig, diff --git a/ceno_zkvm/src/instructions/riscv/jump/test.rs b/ceno_zkvm/src/instructions/riscv/jump/test.rs index 648b17f66..183fc3a55 100644 --- a/ceno_zkvm/src/instructions/riscv/jump/test.rs +++ b/ceno_zkvm/src/instructions/riscv/jump/test.rs @@ -1,5 +1,5 @@ use ceno_emul::{ByteAddr, Change, InsnKind, PC_STEP_SIZE, StepRecord, Word, encode_rv32}; -use goldilocks::GoldilocksExt2; +use ff_ext::GoldilocksExt2; use crate::{ circuit_builder::{CircuitBuilder, ConstraintSystem}, diff --git a/ceno_zkvm/src/instructions/riscv/logic/test.rs b/ceno_zkvm/src/instructions/riscv/logic/test.rs index b35c12bcb..0210b268e 100644 --- a/ceno_zkvm/src/instructions/riscv/logic/test.rs +++ b/ceno_zkvm/src/instructions/riscv/logic/test.rs @@ -1,5 +1,5 @@ use ceno_emul::{Change, StepRecord, Word, encode_rv32}; -use goldilocks::GoldilocksExt2; +use ff_ext::GoldilocksExt2; use crate::{ circuit_builder::{CircuitBuilder, ConstraintSystem}, diff --git a/ceno_zkvm/src/instructions/riscv/logic_imm/logic_imm_circuit.rs b/ceno_zkvm/src/instructions/riscv/logic_imm/logic_imm_circuit.rs index d30b19a4a..e15f194c1 100644 --- a/ceno_zkvm/src/instructions/riscv/logic_imm/logic_imm_circuit.rs +++ b/ceno_zkvm/src/instructions/riscv/logic_imm/logic_imm_circuit.rs @@ -124,7 +124,7 @@ impl LogicConfig { #[cfg(test)] mod test { use ceno_emul::{Change, InsnKind, PC_STEP_SIZE, StepRecord, encode_rv32u}; - use goldilocks::GoldilocksExt2; + use ff_ext::GoldilocksExt2; use crate::{ chip_handler::test::DebugIndex, diff --git a/ceno_zkvm/src/instructions/riscv/memory/gadget.rs b/ceno_zkvm/src/instructions/riscv/memory/gadget.rs index e43d862fe..f0e8e1040 100644 --- a/ceno_zkvm/src/instructions/riscv/memory/gadget.rs +++ b/ceno_zkvm/src/instructions/riscv/memory/gadget.rs @@ -8,9 +8,9 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::StepRecord; -use ff::Field; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; use itertools::izip; +use p3_field::{Field, FieldAlgebra}; pub struct MemWordChange { prev_limb_bytes: Vec, @@ -76,7 +76,7 @@ impl MemWordChange { // extract the least significant byte from u16 limb let rs2_limb_bytes = alloc_bytes(cb, "rs2_limb[0]", 1)?; - let u8_base_inv = E::BaseField::from(1 << 8).invert().unwrap(); + let u8_base_inv = E::BaseField::from_canonical_u64(1 << 8).inverse(); cb.assert_ux::<_, _, 8>( || "rs2_limb[0].le_bytes[1]", u8_base_inv.expr() * (&rs2_limbs[0] - rs2_limb_bytes[0].expr()), @@ -162,40 +162,41 @@ impl MemWordChange { match N_ZEROS { 0 => { for (&col, byte) in izip!(&self.prev_limb_bytes, prev_limb.to_le_bytes()) { - set_val!(instance, col, E::BaseField::from(byte as u64)); + set_val!(instance, col, E::BaseField::from_canonical_u8(byte)); lk_multiplicity.assert_ux::<8>(byte as u64); } set_val!( instance, self.rs2_limb_bytes[0], - E::BaseField::from(rs2_limb.to_le_bytes()[0] as u64) + E::BaseField::from_canonical_u8(rs2_limb.to_le_bytes()[0]) ); rs2_limb.to_le_bytes().into_iter().for_each(|byte| { lk_multiplicity.assert_ux::<8>(byte as u64); }); let change = if low_bits[0] == 0 { - E::BaseField::from(rs2_limb.to_le_bytes()[0] as u64) - - E::BaseField::from(prev_limb.to_le_bytes()[0] as u64) + E::BaseField::from_canonical_u8(rs2_limb.to_le_bytes()[0]) + - E::BaseField::from_canonical_u8(prev_limb.to_le_bytes()[0]) } else { - E::BaseField::from((rs2_limb.to_le_bytes()[0] as u64) << 8) - - E::BaseField::from((prev_limb.to_le_bytes()[1] as u64) << 8) + E::BaseField::from_canonical_u64((rs2_limb.to_le_bytes()[0] as u64) << 8) + - E::BaseField::from_canonical_u64((prev_limb.to_le_bytes()[1] as u64) << 8) }; let final_change = if low_bits[1] == 0 { change } else { - E::BaseField::from(1u64 << 16) * change + E::BaseField::from_canonical_u64(1u64 << 16) * change }; set_val!(instance, self.expected_changes[0], change); set_val!(instance, self.expected_changes[1], final_change); } 1 => { let final_change = if low_bits[1] == 0 { - E::BaseField::from(rs2_limb as u64) - E::BaseField::from(prev_limb as u64) + E::BaseField::from_canonical_u16(rs2_limb) + - E::BaseField::from_canonical_u16(prev_limb) } else { - E::BaseField::from((rs2_limb as u64) << 16) - - E::BaseField::from((prev_limb as u64) << 16) + E::BaseField::from_canonical_u64((rs2_limb as u64) << 16) + - E::BaseField::from_canonical_u64((prev_limb as u64) << 16) }; set_val!(instance, self.expected_changes[0], final_change); } diff --git a/ceno_zkvm/src/instructions/riscv/memory/load.rs b/ceno_zkvm/src/instructions/riscv/memory/load.rs index fff79f2df..4cd1f1650 100644 --- a/ceno_zkvm/src/instructions/riscv/memory/load.rs +++ b/ceno_zkvm/src/instructions/riscv/memory/load.rs @@ -17,8 +17,9 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::{ByteAddr, InsnKind, StepRecord}; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; use itertools::izip; +use p3_field::FieldAlgebra; use std::marker::PhantomData; pub struct LoadConfig { @@ -225,7 +226,11 @@ impl Instruction for LoadInstruction Instruction for LoadInstruction(byte); - set_val!(instance, col, E::BaseField::from(byte)); + for (&col, byte) in izip!(limb_bytes.iter(), target_limb_bytes.into_iter()) { + lk_multiplicity.assert_ux::<8>(byte as u64); + set_val!(instance, col, E::BaseField::from_canonical_u8(byte)); } } let val = match I::INST_KIND { diff --git a/ceno_zkvm/src/instructions/riscv/memory/store.rs b/ceno_zkvm/src/instructions/riscv/memory/store.rs index 29c950957..ca9ffeac0 100644 --- a/ceno_zkvm/src/instructions/riscv/memory/store.rs +++ b/ceno_zkvm/src/instructions/riscv/memory/store.rs @@ -16,7 +16,7 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::{ByteAddr, InsnKind, StepRecord}; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; use std::marker::PhantomData; pub struct StoreConfig { diff --git a/ceno_zkvm/src/instructions/riscv/memory/test.rs b/ceno_zkvm/src/instructions/riscv/memory/test.rs index 4785994d3..427bd899b 100644 --- a/ceno_zkvm/src/instructions/riscv/memory/test.rs +++ b/ceno_zkvm/src/instructions/riscv/memory/test.rs @@ -17,8 +17,7 @@ use crate::{ scheme::mock_prover::{MOCK_PC_START, MockProver}, }; use ceno_emul::{ByteAddr, Change, InsnKind, ReadOp, StepRecord, Word, WriteOp, encode_rv32}; -use ff_ext::ExtensionField; -use goldilocks::GoldilocksExt2; +use ff_ext::{ExtensionField, GoldilocksExt2}; use std::hash::Hash; fn sb(prev: Word, rs2: Word, shift: u32) -> Word { diff --git a/ceno_zkvm/src/instructions/riscv/mul.rs b/ceno_zkvm/src/instructions/riscv/mul.rs index e98a5e8bb..e7b989326 100644 --- a/ceno_zkvm/src/instructions/riscv/mul.rs +++ b/ceno_zkvm/src/instructions/riscv/mul.rs @@ -81,8 +81,9 @@ use std::marker::PhantomData; use ceno_emul::{InsnKind, StepRecord}; -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, SmallField}; +use p3_field::FieldAlgebra; +use p3_goldilocks::Goldilocks; use crate::{ circuit_builder::CircuitBuilder, @@ -173,7 +174,7 @@ impl Instruction for MulhInstructionBas // 32-bit registers represented over the Goldilocks field, so verify // these parameters assert_eq!(UInt::::TOTAL_BITS, u32::BITS as usize); - assert_eq!(E::BaseField::MODULUS_U64, goldilocks::MODULUS); + assert_eq!(E::BaseField::MODULUS_U64, Goldilocks::MODULUS_U64); // 0. Registers and instruction lookup let rs1_read = UInt::new_unchecked(|| "rs1_read", circuit_builder)?; @@ -353,8 +354,8 @@ impl Instruction for MulhInstructionBas } MulhSignDependencies::UU { constrain_rd } => { // assign nonzero value (u32::MAX - rd) - let rd_f = E::BaseField::from(rd as u64); - let avoid_f = E::BaseField::from(u32::MAX.into()); + let rd_f = E::BaseField::from_canonical_u64(rd as u64); + let avoid_f = E::BaseField::from_canonical_u32(u32::MAX); constrain_rd.assign_instance(instance, rd_f, avoid_f)?; // only take the low part of the product @@ -366,8 +367,12 @@ impl Instruction for MulhInstructionBas assert_eq!(prod_lo, rd); let prod_hi = prod >> BIT_WIDTH; - let avoid_f = E::BaseField::from(u32::MAX.into()); - constrain_rd.assign_instance(instance, E::BaseField::from(prod_hi), avoid_f)?; + let avoid_f = E::BaseField::from_canonical_u32(u32::MAX); + constrain_rd.assign_instance( + instance, + E::BaseField::from_canonical_u64(prod_hi), + avoid_f, + )?; prod_hi as u32 } MulhSignDependencies::SU { @@ -401,7 +406,7 @@ impl Instruction for MulhInstructionBas #[cfg(test)] mod test { use ceno_emul::{Change, StepRecord, encode_rv32}; - use goldilocks::GoldilocksExt2; + use ff_ext::GoldilocksExt2; use super::*; use crate::{ diff --git a/ceno_zkvm/src/instructions/riscv/shift.rs b/ceno_zkvm/src/instructions/riscv/shift.rs index e375912af..37aacf642 100644 --- a/ceno_zkvm/src/instructions/riscv/shift.rs +++ b/ceno_zkvm/src/instructions/riscv/shift.rs @@ -11,6 +11,7 @@ use crate::{ instructions::Instruction, set_val, }; +use ff_ext::FieldInto; use super::{RIVInstruction, constants::UInt, r_insn::RInstructionConfig}; diff --git a/ceno_zkvm/src/instructions/riscv/shift_imm.rs b/ceno_zkvm/src/instructions/riscv/shift_imm.rs index 6c1eea6f0..9a848655a 100644 --- a/ceno_zkvm/src/instructions/riscv/shift_imm.rs +++ b/ceno_zkvm/src/instructions/riscv/shift_imm.rs @@ -14,7 +14,7 @@ use crate::{ witness::LkMultiplicity, }; use ceno_emul::{InsnKind, StepRecord}; -use ff_ext::ExtensionField; +use ff_ext::{ExtensionField, FieldInto}; use std::marker::PhantomData; pub struct ShiftImmConfig { diff --git a/ceno_zkvm/src/instructions/riscv/slti.rs b/ceno_zkvm/src/instructions/riscv/slti.rs index 3e0a6e6cb..ceed46174 100644 --- a/ceno_zkvm/src/instructions/riscv/slti.rs +++ b/ceno_zkvm/src/instructions/riscv/slti.rs @@ -20,6 +20,7 @@ use crate::{ utils::i64_to_base, witness::LkMultiplicity, }; +use ff_ext::FieldInto; #[derive(Debug)] pub struct SetLessThanImmConfig { diff --git a/ceno_zkvm/src/scheme/mock_prover.rs b/ceno_zkvm/src/scheme/mock_prover.rs index bbc470db1..d07332d89 100644 --- a/ceno_zkvm/src/scheme/mock_prover.rs +++ b/ceno_zkvm/src/scheme/mock_prover.rs @@ -1243,9 +1243,9 @@ mod tests { set_val, witness::{LkMultiplicity, RowMajorMatrix}, }; - use ff::Field; - use goldilocks::{Goldilocks, GoldilocksExt2}; + use ff_ext::{FieldInto, GoldilocksExt2}; use multilinear_extensions::mle::IntoMLE; + use p3_goldilocks::Goldilocks; #[derive(Debug)] struct AssertZeroCircuit { diff --git a/ceno_zkvm/src/scheme/tests.rs b/ceno_zkvm/src/scheme/tests.rs index ed747fdfe..c13064394 100644 --- a/ceno_zkvm/src/scheme/tests.rs +++ b/ceno_zkvm/src/scheme/tests.rs @@ -6,7 +6,6 @@ use ceno_emul::{ InsnKind::{ADD, ECALL}, Platform, Program, StepRecord, VMState, encode_rv32, }; -use ff::Field; use ff_ext::ExtensionField; use goldilocks::GoldilocksExt2; use itertools::Itertools; diff --git a/ceno_zkvm/src/state.rs b/ceno_zkvm/src/state.rs index 875e8fbfb..7761d9b60 100644 --- a/ceno_zkvm/src/state.rs +++ b/ceno_zkvm/src/state.rs @@ -6,6 +6,7 @@ use crate::{ expression::{Expression, ToExpr}, structs::RAMType, }; +use p3_field::FieldAlgebra; pub trait StateCircuit { fn initial_global_state( @@ -23,7 +24,9 @@ impl StateCircuit for GlobalState { circuit_builder: &mut crate::circuit_builder::CircuitBuilder, ) -> Result, ZKVMError> { let states: Vec> = vec![ - Expression::Constant(E::BaseField::from(RAMType::GlobalState as u64)), + Expression::Constant(E::BaseField::from_canonical_u64( + RAMType::GlobalState as u64, + )), circuit_builder.query_init_pc()?.expr(), circuit_builder.query_init_cycle()?.expr(), ]; @@ -35,7 +38,9 @@ impl StateCircuit for GlobalState { circuit_builder: &mut crate::circuit_builder::CircuitBuilder, ) -> Result, crate::error::ZKVMError> { let states: Vec> = vec![ - Expression::Constant(E::BaseField::from(RAMType::GlobalState as u64)), + Expression::Constant(E::BaseField::from_canonical_u64( + RAMType::GlobalState as u64, + )), circuit_builder.query_end_pc()?.expr(), circuit_builder.query_end_cycle()?.expr(), ]; diff --git a/ceno_zkvm/src/tables/ops/ops_impl.rs b/ceno_zkvm/src/tables/ops/ops_impl.rs index efe7c4de9..f03f74b58 100644 --- a/ceno_zkvm/src/tables/ops/ops_impl.rs +++ b/ceno_zkvm/src/tables/ops/ops_impl.rs @@ -1,7 +1,6 @@ //! The implementation of ops tables. No generics. -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, SmallField}; use itertools::Itertools; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; @@ -16,6 +15,7 @@ use crate::{ structs::ROMType, witness::RowMajorMatrix, }; +use ff_ext::FieldInto; #[derive(Clone, Debug)] pub struct OpTableConfig { diff --git a/ceno_zkvm/src/tables/program.rs b/ceno_zkvm/src/tables/program.rs index 5a43af187..7bad38e70 100644 --- a/ceno_zkvm/src/tables/program.rs +++ b/ceno_zkvm/src/tables/program.rs @@ -15,8 +15,7 @@ use crate::{ use ceno_emul::{ InsnFormat, InsnFormat::*, InsnKind::*, Instruction, PC_STEP_SIZE, Program, WORD_SIZE, }; -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, FieldInto, SmallField}; use itertools::Itertools; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; diff --git a/ceno_zkvm/src/tables/ram/ram_impl.rs b/ceno_zkvm/src/tables/ram/ram_impl.rs index 7f6934cda..0ad0c8dc8 100644 --- a/ceno_zkvm/src/tables/ram/ram_impl.rs +++ b/ceno_zkvm/src/tables/ram/ram_impl.rs @@ -1,8 +1,7 @@ use std::{marker::PhantomData, sync::Arc}; use ceno_emul::{Addr, Cycle, WORD_SIZE}; -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, SmallField}; use itertools::Itertools; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; @@ -19,6 +18,7 @@ use crate::{ structs::ProgramParams, witness::RowMajorMatrix, }; +use ff_ext::FieldInto; use super::{ MemInitRecord, diff --git a/ceno_zkvm/src/tables/range/range_impl.rs b/ceno_zkvm/src/tables/range/range_impl.rs index 6e7ebaee4..0a4f7bac5 100644 --- a/ceno_zkvm/src/tables/range/range_impl.rs +++ b/ceno_zkvm/src/tables/range/range_impl.rs @@ -1,7 +1,6 @@ //! The implementation of range tables. No generics. -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, SmallField}; use rayon::iter::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator}; use std::collections::HashMap; @@ -15,6 +14,7 @@ use crate::{ structs::ROMType, witness::RowMajorMatrix, }; +use ff_ext::FieldInto; #[derive(Clone, Debug)] pub struct RangeTableConfig { diff --git a/ceno_zkvm/src/uint/arithmetic.rs b/ceno_zkvm/src/uint/arithmetic.rs index c2e09b470..f4f9f6982 100644 --- a/ceno_zkvm/src/uint/arithmetic.rs +++ b/ceno_zkvm/src/uint/arithmetic.rs @@ -1,5 +1,4 @@ -use ff_ext::ExtensionField; -use goldilocks::SmallField; +use ff_ext::{ExtensionField, SmallField}; use itertools::{Itertools, izip}; use super::{UIntLimbs, UintLimb}; diff --git a/ceno_zkvm/src/witness.rs b/ceno_zkvm/src/witness.rs index e2db20102..2745f9c02 100644 --- a/ceno_zkvm/src/witness.rs +++ b/ceno_zkvm/src/witness.rs @@ -1,6 +1,6 @@ -use ff::Field; use itertools::izip; use multilinear_extensions::mle::{DenseMultilinearExtension, IntoMLE}; +use p3_field::{Field, FieldAlgebra}; use rayon::{ iter::{IntoParallelIterator, ParallelIterator}, slice::ParallelSliceMut, @@ -27,7 +27,7 @@ use crate::{ #[macro_export] macro_rules! set_val { ($ins:ident, $field:expr, $val:expr) => { - $ins[$field.id as usize] = $val.into(); + $ins[$field.id as usize] = $val.into_f(); }; } @@ -46,7 +46,7 @@ pub struct RowMajorMatrix { padding_strategy: InstancePaddingStrategy, } -impl> RowMajorMatrix { +impl RowMajorMatrix { pub fn new(num_rows: usize, num_col: usize, padding_strategy: InstancePaddingStrategy) -> Self { RowMajorMatrix { values: (0..num_rows * num_col) @@ -89,7 +89,9 @@ impl> RowMajorMatrix let padding_iter = (num_instances..num_instances + num_padding_instances).map(|i| { match &self.padding_strategy { - InstancePaddingStrategy::Custom(fun) => T::from(fun(i as u64, column as u64)), + InstancePaddingStrategy::Custom(fun) => { + T::from_canonical_u64(fun(i as u64, column as u64)) + } InstancePaddingStrategy::RepeatLast if num_instances > 0 => { self[num_instances - 1][column] } @@ -107,7 +109,7 @@ impl> RowMajorMatrix } } -impl> RowMajorMatrix { +impl RowMajorMatrix { pub fn into_mles>( self, ) -> Vec> { diff --git a/ff_ext/src/lib.rs b/ff_ext/src/lib.rs index 9d1018253..a4434ceb3 100644 --- a/ff_ext/src/lib.rs +++ b/ff_ext/src/lib.rs @@ -70,8 +70,20 @@ macro_rules! impl_from_uniform_bytes_for_binomial_extension { impl_from_uniform_bytes_for_binomial_extension!(p3_goldilocks::Goldilocks, 2); +/// define a custom conversion trait like `From` +/// an util to simulate general from function +pub trait FieldFrom { + fn from_v(value: T) -> Self; +} + +/// define a custom trait that relies on `FieldFrom` +/// an util to simulate general into function +pub trait FieldInto { + fn into_f(self) -> T; +} + // TODO remove SmallField -pub trait SmallField: Serialize + P3Field { +pub trait SmallField: Serialize + P3Field + FieldFrom + FieldInto { /// MODULUS as u64 const MODULUS_U64: u64; @@ -105,10 +117,39 @@ pub trait ExtensionField: P3ExtensionField + FromUniformBytes { } mod impl_goldilocks { - use crate::{ExtensionField, FromUniformBytes, GoldilocksExt2, SmallField}; + use crate::{ + ExtensionField, FieldFrom, FieldInto, FromUniformBytes, GoldilocksExt2, SmallField, + }; use p3_field::{FieldAlgebra, FieldExtensionAlgebra, PrimeField64}; use p3_goldilocks::Goldilocks; + impl FieldFrom for Goldilocks { + fn from_v(v: u64) -> Self { + Self::from_canonical_u64(v) + } + } + + impl FieldFrom for GoldilocksExt2 { + fn from_v(v: u64) -> Self { + Self::from_canonical_u64(v) + } + } + + impl FieldInto for T + where + U: FieldFrom, + { + fn into_f(self) -> U { + U::from_v(self) + } + } + + impl FieldInto for Goldilocks { + fn into_f(self) -> Goldilocks { + self + } + } + impl FromUniformBytes for Goldilocks { type Bytes = [u8; 8]; @@ -175,13 +216,3 @@ mod impl_goldilocks { } } } - -#[cfg(test)] -mod test { - use p3_field::TwoAdicField; - use p3_goldilocks::Goldilocks; - #[test] - fn test() { - println!("{:?}", Goldilocks::two_adic_generator(21)); - } -}