Skip to content

feat: bigint circuit to compile #1639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 12, 2025
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion crates/vm/src/arch/testing/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,11 @@ impl<F: PrimeField32> VmChipTestBuilder<F> {
pointer: usize,
writes: Vec<[F; NUM_LIMBS]>,
) {
self.write(1usize, register, [F::from_canonical_usize(pointer)]);
self.write(
1usize,
register,
pointer.to_le_bytes().map(F::from_canonical_u8),
);
for (i, &write) in writes.iter().enumerate() {
self.write(2usize, pointer + i * NUM_LIMBS, write);
}
Expand Down
1 change: 1 addition & 0 deletions extensions/bigint/circuit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ serde.workspace = true
openvm-stark-sdk = { workspace = true }
openvm-circuit = { workspace = true, features = ["test-utils"] }
openvm-rv32-adapters = { workspace = true, features = ["test-utils"] }
test-case.workspace = true

[features]
default = ["parallel", "jemalloc"]
Expand Down
158 changes: 106 additions & 52 deletions extensions/bigint/circuit/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ use openvm_bigint_transpiler::{
};
use openvm_circuit::{
arch::{
SystemConfig, SystemPort, VmExtension, VmInventory, VmInventoryBuilder, VmInventoryError,
ExecutionBridge, SystemConfig, SystemPort, VmExtension, VmInventory, VmInventoryBuilder,
VmInventoryError,
},
system::phantom::PhantomChip,
};
use openvm_circuit_derive::{AnyEnum, InstructionExecutor, VmConfig};
use openvm_circuit_derive::{AnyEnum, InsExecutorE1, InstructionExecutor, VmConfig};
use openvm_circuit_primitives::{
bitwise_op_lookup::{BitwiseOperationLookupBus, SharedBitwiseOperationLookupChip},
range_tuple::{RangeTupleCheckerBus, SharedRangeTupleCheckerChip},
Expand All @@ -25,6 +26,9 @@ use serde::{Deserialize, Serialize};

use crate::*;

// TODO: this should be decided after e2 execution
const MAX_INS_CAPACITY: usize = 1 << 22;

#[derive(Clone, Debug, VmConfig, derive_new::new, Serialize, Deserialize)]
pub struct Int256Rv32Config {
#[system]
Expand Down Expand Up @@ -69,7 +73,7 @@ fn default_range_tuple_checker_sizes() -> [u32; 2] {
[1 << 8, 32 * (1 << 8)]
}

#[derive(ChipUsageGetter, Chip, InstructionExecutor, From, AnyEnum)]
#[derive(ChipUsageGetter, Chip, InstructionExecutor, InsExecutorE1, From, AnyEnum)]
pub enum Int256Executor<F: PrimeField32> {
BaseAlu256(Rv32BaseAlu256Chip<F>),
LessThan256(Rv32LessThan256Chip<F>),
Expand Down Expand Up @@ -101,6 +105,8 @@ impl<F: PrimeField32> VmExtension<F> for Int256 {
program_bus,
memory_bridge,
} = builder.system_port();
let execution_bridge = ExecutionBridge::new(execution_bus, program_bus);

let range_checker_chip = builder.system_base().range_checker_chip.clone();
let bitwise_lu_chip = if let Some(&chip) = builder
.find_chip::<SharedBitwiseOperationLookupChip<8>>()
Expand All @@ -113,8 +119,8 @@ impl<F: PrimeField32> VmExtension<F> for Int256 {
inventory.add_periphery_chip(chip.clone());
chip
};
let offline_memory = builder.system_base().offline_memory();
let address_bits = builder.system_config().memory_config.pointer_max_bits;
// let offline_memory = builder.system_base().offline_memory();
let pointer_max_bits = builder.system_config().memory_config.pointer_max_bits;

let range_tuple_chip = if let Some(chip) = builder
.find_chip::<SharedRangeTupleCheckerChip<2>>()
Expand All @@ -133,103 +139,151 @@ impl<F: PrimeField32> VmExtension<F> for Int256 {
};

let base_alu_chip = Rv32BaseAlu256Chip::new(
Rv32HeapAdapterChip::new(
execution_bus,
program_bus,
memory_bridge,
address_bits,
VmAirWrapper::new(
Rv32HeapAdapterAir::new(
execution_bridge,
memory_bridge,
bitwise_lu_chip.bus(),
pointer_max_bits,
),
BaseAluCoreAir::new(bitwise_lu_chip.bus(), Rv32BaseAlu256Opcode::CLASS_OFFSET),
),
Rv32BaseAlu256Step::new(
Rv32HeapAdapterStep::new(pointer_max_bits, bitwise_lu_chip.clone()),
bitwise_lu_chip.clone(),
Rv32BaseAlu256Opcode::CLASS_OFFSET,
),
BaseAluCoreChip::new(bitwise_lu_chip.clone(), Rv32BaseAlu256Opcode::CLASS_OFFSET),
offline_memory.clone(),
MAX_INS_CAPACITY,
builder.system_base().memory_controller.helper(),
);

inventory.add_executor(
base_alu_chip,
Rv32BaseAlu256Opcode::iter().map(|x| x.global_opcode()),
)?;

let less_than_chip = Rv32LessThan256Chip::new(
Rv32HeapAdapterChip::new(
execution_bus,
program_bus,
memory_bridge,
address_bits,
VmAirWrapper::new(
Rv32HeapAdapterAir::new(
execution_bridge,
memory_bridge,
bitwise_lu_chip.bus(),
pointer_max_bits,
),
LessThanCoreAir::new(bitwise_lu_chip.bus(), Rv32LessThan256Opcode::CLASS_OFFSET),
),
Rv32LessThan256Step::new(
Rv32HeapAdapterStep::new(pointer_max_bits, bitwise_lu_chip.clone()),
bitwise_lu_chip.clone(),
Rv32LessThan256Opcode::CLASS_OFFSET,
),
LessThanCoreChip::new(bitwise_lu_chip.clone(), Rv32LessThan256Opcode::CLASS_OFFSET),
offline_memory.clone(),
MAX_INS_CAPACITY,
builder.system_base().memory_controller.helper(),
);

inventory.add_executor(
less_than_chip,
Rv32LessThan256Opcode::iter().map(|x| x.global_opcode()),
)?;

let branch_equal_chip = Rv32BranchEqual256Chip::new(
Rv32HeapBranchAdapterChip::new(
execution_bus,
program_bus,
memory_bridge,
address_bits,
bitwise_lu_chip.clone(),
VmAirWrapper::new(
Rv32HeapBranchAdapterAir::new(
execution_bridge,
memory_bridge,
bitwise_lu_chip.bus(),
pointer_max_bits,
),
BranchEqualCoreAir::new(Rv32BranchEqual256Opcode::CLASS_OFFSET, DEFAULT_PC_STEP),
),
Rv32BranchEqual256Step::new(
Rv32HeapBranchAdapterStep::new(pointer_max_bits, bitwise_lu_chip.clone()),
Rv32BranchEqual256Opcode::CLASS_OFFSET,
DEFAULT_PC_STEP,
),
BranchEqualCoreChip::new(Rv32BranchEqual256Opcode::CLASS_OFFSET, DEFAULT_PC_STEP),
offline_memory.clone(),
MAX_INS_CAPACITY,
builder.system_base().memory_controller.helper(),
);

inventory.add_executor(
branch_equal_chip,
Rv32BranchEqual256Opcode::iter().map(|x| x.global_opcode()),
)?;

let branch_less_than_chip = Rv32BranchLessThan256Chip::new(
Rv32HeapBranchAdapterChip::new(
execution_bus,
program_bus,
memory_bridge,
address_bits,
bitwise_lu_chip.clone(),
VmAirWrapper::new(
Rv32HeapBranchAdapterAir::new(
execution_bridge,
memory_bridge,
bitwise_lu_chip.bus(),
pointer_max_bits,
),
BranchLessThanCoreAir::new(
bitwise_lu_chip.bus(),
Rv32BranchLessThan256Opcode::CLASS_OFFSET,
),
),
BranchLessThanCoreChip::new(
Rv32BranchLessThan256Step::new(
Rv32HeapBranchAdapterStep::new(pointer_max_bits, bitwise_lu_chip.clone()),
bitwise_lu_chip.clone(),
Rv32BranchLessThan256Opcode::CLASS_OFFSET,
),
offline_memory.clone(),
MAX_INS_CAPACITY,
builder.system_base().memory_controller.helper(),
);
inventory.add_executor(
branch_less_than_chip,
Rv32BranchLessThan256Opcode::iter().map(|x| x.global_opcode()),
)?;

let multiplication_chip = Rv32Multiplication256Chip::new(
Rv32HeapAdapterChip::new(
execution_bus,
program_bus,
memory_bridge,
address_bits,
bitwise_lu_chip.clone(),
VmAirWrapper::new(
Rv32HeapAdapterAir::new(
execution_bridge,
memory_bridge,
bitwise_lu_chip.bus(),
pointer_max_bits,
),
MultiplicationCoreAir::new(*range_tuple_chip.bus(), Rv32Mul256Opcode::CLASS_OFFSET),
),
Rv32Multiplication256Step::new(
Rv32HeapAdapterStep::new(pointer_max_bits, bitwise_lu_chip.clone()),
range_tuple_chip.clone(),
Rv32Mul256Opcode::CLASS_OFFSET,
),
MultiplicationCoreChip::new(range_tuple_chip, Rv32Mul256Opcode::CLASS_OFFSET),
offline_memory.clone(),
MAX_INS_CAPACITY,
builder.system_base().memory_controller.helper(),
);

inventory.add_executor(
multiplication_chip,
Rv32Mul256Opcode::iter().map(|x| x.global_opcode()),
)?;

let shift_chip = Rv32Shift256Chip::new(
Rv32HeapAdapterChip::new(
execution_bus,
program_bus,
memory_bridge,
address_bits,
bitwise_lu_chip.clone(),
VmAirWrapper::new(
Rv32HeapAdapterAir::new(
execution_bridge,
memory_bridge,
bitwise_lu_chip.bus(),
pointer_max_bits,
),
ShiftCoreAir::new(
bitwise_lu_chip.bus(),
range_checker_chip.bus(),
Rv32Shift256Opcode::CLASS_OFFSET,
),
),
ShiftCoreChip::new(
Rv32Shift256Step::new(
Rv32HeapAdapterStep::new(pointer_max_bits, bitwise_lu_chip.clone()),
bitwise_lu_chip.clone(),
range_checker_chip,
range_checker_chip.clone(),
Rv32Shift256Opcode::CLASS_OFFSET,
),
offline_memory.clone(),
MAX_INS_CAPACITY,
builder.system_base().memory_controller.helper(),
);

inventory.add_executor(
shift_chip,
Rv32Shift256Opcode::iter().map(|x| x.global_opcode()),
Expand Down
Loading
Loading