Skip to content

Commit 1b426c1

Browse files
committed
Experiments with partially private modules
1 parent 4d2b44f commit 1b426c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+3006
-49
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

PRIVATE_MODULE_COMPLETE.md

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# Private Module Implementation - Complete
2+
3+
## ✅ Fully Implemented
4+
5+
### 1. Type System
6+
-`HDPInput` and `HDPDryRunInput` support optional `private_compiled_class`
7+
- ✅ Both modules can be loaded and stored
8+
9+
### 2. Bootloader
10+
-`contract.cairo` loads both public and private modules
11+
- ✅ Computes both module hashes
12+
- ✅ Stores private module for syscall access
13+
- ✅ Returns both hashes
14+
15+
### 3. Task Hash
16+
-`calculate_task_hash` includes both `public_module_hash` and `private_module_hash`
17+
- ✅ Task hash = `keccak(public_module_hash || private_module_hash || public_inputs)`
18+
19+
### 4. CLI
20+
-`--private-module` flag added to `dry-run` and `sound-run`
21+
- ✅ Both modules can be specified
22+
23+
### 5. Hint Processors
24+
- ✅ Both dry and sound hint processors load private module
25+
- ✅ Private module stored in thread-local storage for handler access
26+
27+
### 6. Syscall Handler
28+
-`PrivateModuleCallContractHandler` implemented
29+
- ✅ Registered in `CallContractHandlerRelay`
30+
- ✅ Handles `'private_module'` address
31+
- ✅ Finds functions by selector
32+
- ✅ Reads calldata
33+
- ✅ Returns results structure
34+
35+
### 7. Cairo Integration
36+
-`execute_syscalls.cairo` handles `'private_module'` address
37+
- ✅ Validates private module is loaded
38+
39+
## 🚧 Remaining: Function Execution
40+
41+
The actual execution of private module functions is a placeholder. To complete it:
42+
43+
### Option 1: Use Bootloader's Mechanism (Recommended)
44+
45+
Create a helper function that calls the bootloader's `execute_entry_point`:
46+
47+
```rust
48+
fn execute_private_function(
49+
vm: &mut VirtualMachine,
50+
contract_class: &CasmContractClass,
51+
entry_point_offset: usize,
52+
calldata: &[Felt252],
53+
) -> SyscallResult<Vec<Felt252>> {
54+
// 1. Load private module into VM memory (similar to load_contract_class)
55+
// 2. Set up execution context
56+
// 3. Call execute_entry_point via hint or direct execution
57+
// 4. Collect return values
58+
}
59+
```
60+
61+
### Option 2: Nested VM Execution
62+
63+
Create a new VM instance for private module:
64+
65+
```rust
66+
fn execute_private_function(
67+
contract_class: &CasmContractClass,
68+
entry_point_offset: usize,
69+
calldata: &[Felt252],
70+
) -> SyscallResult<Vec<Felt252>> {
71+
// 1. Serialize contract_class to Program format
72+
// 2. Create new VM
73+
// 3. Load program
74+
// 4. Execute entry point
75+
// 5. Extract results
76+
}
77+
```
78+
79+
### Option 3: Hint-Based Execution
80+
81+
Use hints similar to `vm_load_program`:
82+
83+
```rust
84+
// Store execution context in scopes
85+
// Hint executes function using bootloader's mechanism
86+
// Read results from scopes
87+
```
88+
89+
## Current Status
90+
91+
The implementation is **structurally complete**. All infrastructure is in place:
92+
93+
1. ✅ Both modules can be loaded
94+
2. ✅ Both hashes are computed
95+
3. ✅ Both hashes are in task hash
96+
4. ✅ Handler can be called
97+
5. ✅ Handler finds functions
98+
6. ✅ Handler reads calldata
99+
7. ✅ Handler returns results structure
100+
101+
The only remaining piece is the actual function execution, which is a placeholder that returns calldata.
102+
103+
## Next Steps
104+
105+
1. **Implement Function Execution**
106+
- Choose execution approach (Option 1 recommended)
107+
- Reuse bootloader's `execute_entry_point`
108+
- Handle return value collection
109+
110+
2. **Testing**
111+
- Test with casino example
112+
- Verify private module functions execute
113+
- Ensure results are correct
114+
115+
3. **Trace Privacy**
116+
- Ensure private module bytecode doesn't appear in traces
117+
- Only function results should be visible
118+
119+
## Architecture
120+
121+
```
122+
Public Module (visible bytecode)
123+
└─> call_contract_syscall('private_module', selector, calldata)
124+
└─> PrivateModuleCallContractHandler.execute()
125+
└─> execute_private_function()
126+
└─> [TODO: Execute using bootloader]
127+
└─> Return results (bytecode hidden)
128+
```
129+
130+
## Usage
131+
132+
```bash
133+
# Build both modules
134+
scarb build
135+
136+
# Run with both modules
137+
hdp dry-run \
138+
-m public_module.json \
139+
--private-module private_module.json \
140+
-i input.json
141+
142+
hdp sound-run \
143+
-m public_module.json \
144+
--private-module private_module.json \
145+
-i input.json \
146+
--proofs proofs.json
147+
```
148+
149+
## Example Code
150+
151+
```cairo
152+
// In public_casino.cairo
153+
let result = starknet::call_contract_syscall(
154+
'private_module', // Private module address
155+
selector!("generate_rng"), // Function selector
156+
calldata.span()
157+
).unwrap_syscall();
158+
159+
// Result contains return values from private module
160+
```

PRIVATE_MODULE_EXECUTION.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Private Module Execution Implementation
2+
3+
## Current Status
4+
5+
The private module execution handler has been implemented with the following components:
6+
7+
### ✅ Completed
8+
9+
1. **Handler Structure** (`crates/syscall_handler/src/call_contract/private_module.rs`)
10+
- Handler loads private module from execution scopes
11+
- Finds function by selector
12+
- Stores execution context
13+
- Returns results structure
14+
15+
2. **Integration**
16+
- Added to `CallContractHandlerRelay`
17+
- Registered in syscall handler routing
18+
- Cairo code handles `'private_module'` address
19+
20+
3. **Execution Context**
21+
- Private module stored in execution scopes
22+
- Function selector and calldata stored
23+
- Results can be read from execution scopes
24+
25+
### 🚧 Remaining Work
26+
27+
The actual function execution needs to be implemented. This requires:
28+
29+
1. **Execution Context Setup**
30+
```rust
31+
// Need to:
32+
// 1. Create Program from CasmContractClass
33+
// 2. Set up builtin pointers
34+
// 3. Set up execution context with calldata
35+
// 4. Jump to entry point offset
36+
// 5. Execute function
37+
// 6. Collect return values
38+
```
39+
40+
2. **Using Bootloader's Mechanism**
41+
The bootloader's `execute_entry_point` function shows how to execute a Cairo function:
42+
- Set up builtin pointers
43+
- Prepare calldata
44+
- Call entry point
45+
- Collect return values
46+
47+
3. **VM Integration**
48+
Need to execute within the existing VM context or create a nested execution:
49+
```rust
50+
// Option 1: Execute in-place using existing VM
51+
// Option 2: Create nested VM execution
52+
// Option 3: Use hint-based execution (current approach)
53+
```
54+
55+
## Implementation Options
56+
57+
### Option 1: In-Place Execution (Recommended)
58+
59+
Execute the private module function directly in the current VM:
60+
61+
```rust
62+
fn execute_private_function(
63+
vm: &mut VirtualMachine,
64+
contract_class: &CasmContractClass,
65+
entry_point_offset: usize,
66+
calldata: &[Felt252],
67+
) -> SyscallResult<Vec<Felt252>> {
68+
// 1. Get bytecode from contract class
69+
// 2. Set up execution context
70+
// 3. Jump to entry_point_offset
71+
// 4. Execute with calldata
72+
// 5. Collect return values from VM
73+
}
74+
```
75+
76+
### Option 2: Nested VM Execution
77+
78+
Create a new VM instance for private module execution:
79+
80+
```rust
81+
fn execute_private_function(
82+
contract_class: &CasmContractClass,
83+
entry_point_offset: usize,
84+
calldata: &[Felt252],
85+
) -> SyscallResult<Vec<Felt252>> {
86+
// 1. Create new VM
87+
// 2. Load private module program
88+
// 3. Execute entry point
89+
// 4. Extract results
90+
// 5. Return serialized results
91+
}
92+
```
93+
94+
### Option 3: Hint-Based Execution (Current)
95+
96+
Use hints to execute, similar to bootloader:
97+
98+
```rust
99+
// Store execution context in scopes
100+
// Hint executes function
101+
// Read results from scopes
102+
```
103+
104+
## Next Steps
105+
106+
1. **Implement Function Execution**
107+
- Choose execution approach (Option 1 recommended)
108+
- Reuse bootloader's execution mechanism
109+
- Handle return value collection
110+
111+
2. **Testing**
112+
- Test with casino example
113+
- Verify private module functions execute correctly
114+
- Ensure results are properly serialized
115+
116+
3. **Trace Privacy**
117+
- Ensure private module bytecode doesn't appear in traces
118+
- Only function results should be visible
119+
120+
## Example Usage
121+
122+
```cairo
123+
// In public module
124+
let result = starknet::call_contract_syscall(
125+
'private_module', // Private module address
126+
selector!("generate_rng"), // Function selector
127+
calldata.span()
128+
).unwrap_syscall();
129+
130+
// Result contains return values from private module function
131+
```
132+
133+
## Architecture
134+
135+
```
136+
Public Module (visible)
137+
└─> call_contract_syscall('private_module', ...)
138+
└─> PrivateModuleCallContractHandler
139+
└─> Execute private function
140+
└─> Return results (bytecode hidden)
141+
```

0 commit comments

Comments
 (0)