Skip to content

Commit

Permalink
Merge pull request #2903 from o1-labs/dw/div-by-zero
Browse files Browse the repository at this point in the history
o1vm/riscv32im: div by zero for DIV and DIVU
  • Loading branch information
dannywillems authored Dec 24, 2024
2 parents 997b51b + 27a0dd4 commit 639b0cb
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
Binary file added o1vm/resources/programs/riscv32im/bin/div_by_zero
Binary file not shown.
Binary file added o1vm/resources/programs/riscv32im/bin/divu_by_zero
Binary file not shown.
19 changes: 19 additions & 0 deletions o1vm/resources/programs/riscv32im/src/div_by_zero.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.section .text
.globl _start

_start:
# Signed division by zero (div)
li t0, 42 # t0 = 42
li t1, 0 # t1 = 0
div t2, t0, t1 # t2 = t0 / t1 (Expected: division by zero)

# Custom exit syscall
li a0, 0
li a1, 0
li a2, 0
li a3, 0
li a4, 0
li a5, 0
li a6, 0
li a7, 42
ecall
19 changes: 19 additions & 0 deletions o1vm/resources/programs/riscv32im/src/divu_by_zero.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.section .text
.globl _start

_start:
# Unsigned division by zero (div)
li t0, 42 # t0 = 42
li t1, 0 # t1 = 0
divu t2, t0, t1 # t2 = t0 / t1 (Expected: division by zero)

# Custom exit syscall
li a0, 0
li a1, 0
li a2, 0
li a3, 0
li a4, 0
li a5, 0
li a6, 0
li a7, 42
ecall
8 changes: 8 additions & 0 deletions o1vm/src/interpreters/riscv32im/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1280,6 +1280,10 @@ pub trait InterpreterEnv {
/// There are no constraints on the returned values; callers must manually add constraints to
/// ensure that the pair of returned values correspond to the given values `x` and `y`, and
/// that they fall within the desired range.
///
/// Division by zero will create a panic! exception. The RISC-V
/// specification leaves the case unspecified, and therefore we prefer to
/// forbid this case while building the witness.
unsafe fn div_signed(
&mut self,
x: &Self::Variable,
Expand Down Expand Up @@ -1308,6 +1312,10 @@ pub trait InterpreterEnv {
/// There are no constraints on the returned values; callers must manually add constraints to
/// ensure that the pair of returned values correspond to the given values `x` and `y`, and
/// that they fall within the desired range.
///
/// Division by zero will create a panic! exception. The RISC-V
/// specification leaves the case unspecified, and therefore we prefer to
/// forbid this case while building the witness.
unsafe fn div(
&mut self,
x: &Self::Variable,
Expand Down
30 changes: 30 additions & 0 deletions o1vm/tests/test_riscv_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,33 @@ fn test_slt() {
assert_eq!(witness.registers[T5], 0);
assert_eq!(witness.registers[T6], 0);
}

#[test]
#[should_panic]
fn test_div_by_zero() {
let curr_dir = std::env::current_dir().unwrap();
let path = curr_dir.join(std::path::PathBuf::from(
"resources/programs/riscv32im/bin/div_by_zero",
));
let state = o1vm::elf_loader::parse_riscv32(&path).unwrap();
let mut witness = Env::<Fp>::create(PAGE_SIZE.try_into().unwrap(), state);

while !witness.halt {
witness.step();
}
}

#[test]
#[should_panic]
fn test_divu_by_zero() {
let curr_dir = std::env::current_dir().unwrap();
let path = curr_dir.join(std::path::PathBuf::from(
"resources/programs/riscv32im/bin/divu_by_zero",
));
let state = o1vm::elf_loader::parse_riscv32(&path).unwrap();
let mut witness = Env::<Fp>::create(PAGE_SIZE.try_into().unwrap(), state);

while !witness.halt {
witness.step();
}
}

0 comments on commit 639b0cb

Please sign in to comment.