jolt
jolt copied to clipboard
Move R1CS constraints out of Jolt proof
Currently, a JoltProof
consists of an R1CSProof
, which in turn consists of a UniformSpartanKey
and a UniformSpartanProof
. The former one, UniformSpartanKey
, contains the R1CS constraints for Jolt. These constraints are publicly derivable from the RISC-V sequence of instructions (i.e. an object of the form Vec<ELFInstruction>
).
Because of this, UniformSpartanKey
should not be part of a Jolt proof, and instead should be moved to JoltPreprocessing
. Otherwise, a malicious prover can send empty constraints, and the verifier will accept the R1CSProof
.
When moved to JoltPreprocessing
, the verifier will itself do the work of generating R1CS constraints, and hence cannot be fooled by the prover to use a different set of constraints.
Relevant code:
pub struct JoltProof<const C: usize, const M: usize, F, PCS, InstructionSet, Subtables>
where
F: JoltField,
PCS: CommitmentScheme<Field = F>,
InstructionSet: JoltInstructionSet,
Subtables: JoltSubtableSet<F>,
{
pub trace_length: usize,
pub program_io: JoltDevice,
pub bytecode: BytecodeProof<F, PCS>,
pub read_write_memory: ReadWriteMemoryProof<F, PCS>,
pub instruction_lookups: InstructionLookupsProof<C, M, F, PCS, InstructionSet, Subtables>,
pub r1cs: R1CSProof<F, PCS>,
}
pub struct R1CSProof<F: JoltField, C: CommitmentScheme<Field = F>> {
pub key: UniformSpartanKey<F>,
pub proof: UniformSpartanProof<F, C>,
}
pub struct UniformSpartanKey<F: JoltField> {
pub uniform_r1cs: UniformR1CS<F>,
pub offset_eq_r1cs: NonUniformR1CS<F>,
/// Number of constraints across all steps padded to nearest power of 2
pub num_cons_total: usize,
/// Number of steps padded to the nearest power of 2
pub num_steps: usize,
/// Digest of verifier key
pub(crate) vk_digest: F,
}