Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0207e3d
Basic rv32im fuzzer
0xddom Mar 10, 2026
9b749e5
Change target VM for fuzzing and include example guests written in C
0xddom Mar 12, 2026
d93b2fc
Write test
0xddom Mar 12, 2026
288e043
Compliance tests
0xddom Mar 25, 2026
81db541
Update list of passing tests after run with prover
0xddom Mar 26, 2026
44854a9
Preparations for prover fuzzing
0xddom Mar 26, 2026
95ed05e
Beginnings of trace factory abstraction
0xddom Mar 27, 2026
5f813c7
Fuzzer scaffold
0xddom Mar 27, 2026
72b5ae4
Closer to an e2e setup
0xddom Mar 27, 2026
c910c00
More e2e stuff
0xddom Mar 31, 2026
d49a4f8
Fix hash function
0xddom Mar 31, 2026
87fa697
e2e run with no-op mutator
0xddom Mar 31, 2026
9beb3d8
Make worker count configurable
0xddom Mar 31, 2026
9a58d0d
A bit nicer UI
0xddom Mar 31, 2026
cda5533
Add more circuits to the fuzzer
0xddom Mar 31, 2026
518f904
Add load/store circuits
0xddom Mar 31, 2026
6d37cd2
Preparations for mutators
0xddom Mar 31, 2026
2e1560c
Mutators
0xddom Apr 1, 2026
3b150bd
Update doc
0xddom Apr 1, 2026
54d75b3
Triage command
0xddom Apr 6, 2026
f07a4ea
Add logging
0xddom Apr 7, 2026
70a0961
Fix typo
0xddom Apr 7, 2026
a95053c
Polish mutators
0xddom Apr 8, 2026
b55b7e5
Pending changes
0xddom May 4, 2026
ca7eb95
Adjust setup
0xddom May 5, 2026
ec087d8
Cleanup
0xddom May 11, 2026
f4a049f
Add readme instructions
0xddom May 11, 2026
de375c3
Remove soft link
0xddom May 11, 2026
6df25f5
More tweaks
0xddom May 11, 2026
49c5b01
Rollback changes in client code
0xddom May 11, 2026
a143cb6
Apply suggestions from code review
0xddom May 11, 2026
ff719e2
Remove script
0xddom May 11, 2026
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
rustc-ice-*.*
.DS_Store
**/.DS_Store
fuzzing-runs
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,7 @@ debug = true # Disable debug info to reduce compile time (optional, set
# strip = "symbols" # Strip symbols to reduce binary size and linking time
# panic = "unwind" # Default panic strategy, no change needed (abort can be faster but less safe for tests)
rpath = false # Disable rpath (rarely needed, speeds up linking slightly)

[profile.compliance-tests]
inherits = "release"
debug-assertions = true
4 changes: 4 additions & 0 deletions c_examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.bin
*.text
*.asm
*.text
27 changes: 27 additions & 0 deletions c_examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CC=riscv64-elf-gcc
CFLAGS=-march=rv32im_zicsr -mabi=ilp32 -nostdlib -O0 -nolibc -fno-builtin -ffreestanding -T memmap.ld
OBJCOPY=riscv64-elf-objcopy

.PHONY: clean all hello badread badread2 badwrite

all: hello badread badread2

hello: hello.bin hello.text
badread: badread.bin badread.text
badread2: badread2.bin badread2.text
badwrite: badwrite.bin badwrite.text

%.elf: %.c rt.c start.s uart.c
${CC} ${CFLAGS} -o $@ $^

%.bin: %.elf
${OBJCOPY} -O binary $^ $@

%.text: %.elf
${OBJCOPY} -O binary --only-section=.text $^ $@

%.asm: %.c
${CC} ${CFLAGS} -o $@ $^ -S

clean:
rm -rf *.elf *.bin *.text *.asm
15 changes: 15 additions & 0 deletions c_examples/badread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "rt.h"

#define HEAP_ADDR (void *)0x04000000

void func(unsigned int *count) { (*count)++; }

Result main() {
void *heap = HEAP_ADDR;
// unsigned int *count = (unsigned int *)heap;
void (*f)() = (void (*)())(heap);

(*f)();

return success(0, 0, 0, 0, 0, 0, 0, 0);
}
14 changes: 14 additions & 0 deletions c_examples/badread2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "rt.h"

#define RAM_SIZE (1 << 30)
#define HEAP_ADDR (void *)(RAM_SIZE)

void func(unsigned int *count) { (*count)++; }

Result main() {
void *heap = HEAP_ADDR;
unsigned int *values = (unsigned int *)heap;

return success(values[0], values[10], values[20], values[30], values[40],
values[50], values[60], values[70]);
}
29 changes: 29 additions & 0 deletions c_examples/badwrite.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "rt.h"

#define RAM_SIZE (1 << 30)
#define HEAP_ADDR (void *)(RAM_SIZE)

void func(unsigned int *count) { (*count)++; }

Result main() {
void *heap = HEAP_ADDR;
unsigned int *values = (unsigned int *)heap;

// Vali d wr ite!
// 0x696c6156 0x72772064 0x21657469
unsigned int *valid = values - 5;
valid[0] = 0x696c6156;
valid[1] = 0x72772064;
valid[2] = 0x21657469;

// Hell o fr om t he G uest
// 0x6c6c6548 0x7266206f 0x74206d6f 0x47206568 0x74736575
values[1] = 0x6c6c6548;
values[2] = 0x7266206f;
values[3] = 0x74206d6f;
values[4] = 0x47206568;
values[5] = 0x74736575;

return success(values[0], values[10], values[20], values[30], values[40],
values[50], values[60], values[70]);
}
7 changes: 7 additions & 0 deletions c_examples/hello.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "rt.h"

#define ch(c) ((unsigned int)c)

Result main() {
return success(ch('H'), ch('e'), ch('l'), ch('l'), ch('o'), ch('\n'), 0, 0);
}
22 changes: 22 additions & 0 deletions c_examples/memmap.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
STACK_SIZE = 0x100000; /* 1 MB */

SECTIONS
{
.text 0x00000000 : { *(.text.start) *(.text*) }
__text_end = .;
.rodata : { *(.rodata*) *(.srodata*) }
.data ALIGN(0x20000) : { *(.sdata*) }
__bss_start = .;
.bss : { *(.bss*) *(.sbss*) *(COMMON) }
__bss_end = .;
.heap 0x04000000 : { __heap_start = .; }
.stack 0x10000000 - STACK_SIZE : {
__heap_max = .;
. = . + STACK_SIZE;
__stack_top = .;
}
__elf_start = .;
}

ASSERT(_start == ADDR(.text), /* error if _start not at correct address */
"_start symbol must be placed first in text section")
58 changes: 58 additions & 0 deletions c_examples/rt.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Runtime file that defines the _start function.

#include "rt.h"

void _start_c() {
Result result = main();
unsigned int *ptr = result.data;
asm("lw x10, 0(%0)\n\t"
"lw x11, 4(%0)\n\t"
"lw x12, 8(%0)\n\t"
"lw x13, 12(%0)\n\t"
"lw x14, 16(%0)\n\t"
"lw x15, 20(%0)\n\t"
"lw x16, 24(%0)\n\t"
"lw x17, 28(%0)\n\t"
"lw x18, 32(%0)\n\t"
"lw x19, 36(%0)\n\t"
"lw x20, 40(%0)\n\t"
"lw x21, 44(%0)\n\t"
"lw x22, 48(%0)\n\t"
"lw x23, 52(%0)\n\t"
"lw x24, 56(%0)\n\t"
"lw x25, 60(%0)\n\t"
:
: "r"(ptr)
: "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19",
"x20", "x21", "x22", "x23", "x24", "x25");

for (;;) {
}
__builtin_unreachable();
}

void write_csr_word(unsigned int word) {
// csrrw x0, 0x7c0, {rd}
asm("csrrw x0, 0x7c0, %0" : : "r"(word) : "x0");
}

void *memset(void *b, int c, unsigned int len) {
for (int i = 0; i < len; i++) {
*(((unsigned char *)b) + i) = (unsigned char)c;
}
return b;
}

Result success(unsigned int d0, unsigned int d1, unsigned int d2,
unsigned int d3, unsigned int d4, unsigned int d5,
unsigned int d6, unsigned int d7) {
return (Result){.data = {d0, d1, d2, d3, d4, d5, d6, d7}};
}

unsigned strlen(const char *s) {
unsigned i = 0;
for (; s[i] != '\0'; i++) {
}

return i;
}
17 changes: 17 additions & 0 deletions c_examples/rt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef _RT_H
#define _RT_H

typedef struct Result {
unsigned int data[16];
} Result;

Result main();

Result success(unsigned int, unsigned int, unsigned int, unsigned int,
unsigned int, unsigned int, unsigned int, unsigned int);

void write_csr_word(unsigned int word);

unsigned strlen(const char *);

#endif
31 changes: 31 additions & 0 deletions c_examples/start.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

.attribute arch, "rv32im"

# Identify this section to linker script memmap.ld
.section ".text.start"

.type _start, @function
.global _start
.global __stack_top


_start:
la ra, _abs_start
jr ra

_abs_start:
.cfi_startproc
.cfi_undefined ra

# .option push
# .option norelax
# la gp, __global_pointer$
# .option pop

la sp, __stack_top

add s0, sp, zero

jal zero, _start_c

.cfi_endproc
18 changes: 18 additions & 0 deletions c_examples/uart.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "uart.h"
#include "rt.h"

void uart_print_msg(const char *msg) {
write_csr_word(0xffffffff);
unsigned len = strlen(msg);
unsigned words = len / 4;
if (len % 4 != 0) {
words++;
}
write_csr_word(len);
for (unsigned word = 0; word < words; word++) {
unsigned *ptr = (unsigned *)msg;
if (word * 4 < len) {
write_csr_word(ptr[word]);
}
}
}
8 changes: 8 additions & 0 deletions c_examples/uart.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _UART_H
#define _UART_H

#include "rt.h"

void uart_print_msg(const char *);

#endif
14 changes: 14 additions & 0 deletions examples/basic_fibonacci/Cargo.lock

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

14 changes: 14 additions & 0 deletions examples/dynamic_fibonacci/Cargo.lock

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

42 changes: 42 additions & 0 deletions fuzzing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,52 @@ categories.workspace = true
name = "witgen-fuzz"
path = "src/bin/witgen.rs"

[[bin]]
name = "rv32im-afl"
path = "src/bin/rv32im.rs"

[[bin]]
name = "prover-fuzz"
path = "src/bin/prover.rs"

[dependencies]
clap = { workspace = true }
env_logger = "0.11"
log = "0.4"
serde = { workspace = true, features = ["derive"] }
serde_json = "*"
anyhow = "1"
similar = "2"

# witgen dependencies
prover = { workspace = true, features = ["prover"] }
add_sub_lui_auipc_mop = { path = "../circuit_defs/unrolled_circuits/add_sub_lui_auipc_mop" }
rand = "0.10"
sha2 = "0.10"
verifier_common = { workspace = true, features = ["proof_utils", "replace_csr"] }
add_sub_lui_auipc_mop_verifier = { path = "../circuit_defs/unrolled_circuits/add_sub_lui_auipc_mop/verifier", features = ["proof_utils", "replace_csr"] }
inits_and_teardowns_verifier = { path = "../circuit_defs/unrolled_circuits/inits_and_teardowns/verifier", features = ["proof_utils", "replace_csr"] }
jump_branch_slt_verifier = { path = "../circuit_defs/unrolled_circuits/jump_branch_slt/verifier", features = ["proof_utils", "replace_csr"] }
load_store_subword_only_verifier = { path = "../circuit_defs/unrolled_circuits/load_store_subword_only/verifier", features = ["proof_utils", "replace_csr"] }
load_store_word_only_verifier = { path = "../circuit_defs/unrolled_circuits/load_store_word_only/verifier", features = ["proof_utils", "replace_csr"] }
mul_div_unsigned_verifier = { path = "../circuit_defs/unrolled_circuits/mul_div_unsigned/verifier", features = ["proof_utils", "replace_csr"] }
shift_binary_csr_verifier = { path = "../circuit_defs/unrolled_circuits/shift_binary_csr/verifier", features = ["proof_utils", "replace_csr"] }

# rv32im dependencies
afl = "0.17"
riscv_transpiler = { path = "../riscv_transpiler/", features = ["fuzzing-support"] }
# risc_v_simulator = { path = "../risc_v_simulator" }
unicorn-engine = "2.1.5"

[target.'cfg(unix)'.dependencies]
libc = {version = "0.2", optional = true }

[dev-dependencies]
rstest = "0.26"
simplelog = {version = "0.12", features = ["test"] }

[features]
default = []
prover = ["prover/test"]
prover-messages = []
mute = ["dep:libc"]
Loading
Loading