Instructions and Types
StoffelVM is a register-based virtual machine optimized for Multi-Party Computation. This page documents the complete instruction set and type system.Architecture Overview
- Register-based: Operations use numbered registers rather than a stack
- Dual register sets: Separate registers for clear (public) and secret values
- 32 registers: Registers 0-15 for clear values, 16-31 for secret values
- Compare flag: Single flag for conditional jumps
Value Types
Primitive Types
| Type | Description | Size |
|---|---|---|
I64 | Signed 64-bit integer | 8 bytes |
I32 | Signed 32-bit integer | 4 bytes |
I16 | Signed 16-bit integer | 2 bytes |
I8 | Signed 8-bit integer | 1 byte |
U64 | Unsigned 64-bit integer | 8 bytes |
U32 | Unsigned 32-bit integer | 4 bytes |
U16 | Unsigned 16-bit integer | 2 bytes |
U8 | Unsigned 8-bit integer | 1 byte |
Float | Fixed-point number (stored as I64) | 8 bytes |
Bool | Boolean value | 1 byte |
String | UTF-8 string | Variable |
Unit | Nil/void value | 0 bytes |
Complex Types
| Type | Description |
|---|---|
Object | Key-value map (reference) |
Array | Indexed collection (reference) |
Closure | Function with captured environment |
Foreign | Rust object exposed via FFI |
Share | Secret-shared value for MPC |
Share Types (MPC)
Secret-shared values carry a type tag:Instruction Set
Memory Operations
LD - Load from Stack
Load a value from the stack into a register.dest_reg: Target register (0-31)stack_offset: Offset from stack base
LDI - Load Immediate
Load a constant value into a register.dest_reg: Target register (0-31)constant_index: Index into constant pool
MOV - Move
Copy value from one register to another.dest_reg: Target register (0-31)src_reg: Source register (0-31)
PUSHARG - Push Argument
Push a register value onto the argument stack for function calls.src_reg: Register containing the argument
Arithmetic Operations
All arithmetic operations follow the pattern:| Instruction | Operation | Description |
|---|---|---|
ADD | dest = src1 + src2 | Addition |
SUB | dest = src1 - src2 | Subtraction |
MUL | dest = src1 * src2 | Multiplication |
DIV | dest = src1 / src2 | Integer division |
MOD | dest = src1 % src2 | Modulo |
Bitwise Operations
| Instruction | Operation | Description |
|---|---|---|
AND | dest = src1 & src2 | Bitwise AND |
OR | dest = src1 | src2 | Bitwise OR |
XOR | dest = src1 ^ src2 | Bitwise XOR |
NOT | dest = ~src | Bitwise NOT (unary) |
SHL | dest = src << amount | Shift left |
SHR | dest = src >> amount | Shift right |
NOT only takes two operands: NOT dest_reg, src_reg
Example:
Comparison Operation
CMP - Compare
Compare two registers and set the compare flag.-1ifreg1 < reg20ifreg1 == reg21ifreg1 > reg2
Control Flow
JMP - Unconditional Jump
Jump to a labeled instruction.Conditional Jumps
Jump based on the compare flag (set byCMP):
| Instruction | Condition | Description |
|---|---|---|
JMPEQ | flag == 0 | Jump if equal |
JMPNEQ | flag != 0 | Jump if not equal |
JMPLT | flag == -1 | Jump if less than |
JMPGT | flag == 1 | Jump if greater than |
Function Operations
CALL - Call Function
Call a function by name or index.- Arguments must be pushed with
PUSHARGbefore calling - Creates new activation record
- Jumps to function entry point
RET - Return
Return from function with a value.src_reg: Register containing return value- Pops activation record
- Returns control to caller
Opcode Encoding
Instructions are encoded as bytes with the following opcodes:| Opcode | Hex | Instruction |
|---|---|---|
| 0 | 0x00 | LD |
| 1 | 0x01 | LDI |
| 2 | 0x02 | MOV |
| 3 | 0x03 | ADD |
| 4 | 0x04 | SUB |
| 5 | 0x05 | MUL |
| 6 | 0x06 | DIV |
| 7 | 0x07 | MOD |
| 8 | 0x08 | AND |
| 9 | 0x09 | OR |
| 10 | 0x0A | XOR |
| 11 | 0x0B | NOT |
| 12 | 0x0C | SHL |
| 13 | 0x0D | SHR |
| 14 | 0x0E | JMP |
| 15 | 0x0F | JMPEQ |
| 16 | 0x10 | JMPNEQ |
| 17 | 0x11 | CALL |
| 18 | 0x12 | RET |
| 19 | 0x13 | PUSHARG |
| 20 | 0x14 | CMP |
| 21 | 0x15 | JMPLT |
| 22 | 0x16 | JMPGT |
Bytecode Format
Compiled programs use the.stfb or .stfbin extension:
Execution Model
Activation Records
Each function call creates an activation record containing:- Function name
- Local variables (HashMap)
- Registers (SmallVec, optimized for 16)
- Instructions
- Upvalues (for closures)
- Argument stack
- Compare flag
- Instruction pointer
Register Allocation
- Registers 0-15: Clear (public) values
- Registers 16-31: Secret (MPC) values
- Compiler performs graph-coloring register allocation
- Spills to stack when registers exhausted
Constant Pool
Constants are stored in a separate pool and referenced by index:- Reduces instruction size
- Enables deduplication
- Supports all value types
MPC Integration
For MPC operations, the VM integrates with the HoneyBadger protocol:Secret Operations
When operating onShare values:
- Arithmetic uses secure MPC protocols
multiply_share()uses Beaver triplesopen_share()reconstructs values
Client Input
TheClientStore provides access to client inputs:
take_share(party_id, index)retrieves secret sharesget_number_clients()returns participant count
Next Steps
- Implementation Details: VM architecture deep dive
- Built-in Functions: Standard library functions
- Using the VM: Running programs