-
Notifications
You must be signed in to change notification settings - Fork 17
Range checks #71
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
base: main
Are you sure you want to change the base?
Range checks #71
Conversation
f8d87cb to
1cb93fe
Compare
crates/lean_compiler/src/lib.rs
Outdated
| pub fn compile_program( | ||
| program: &str, | ||
| public_input: &[F], | ||
| private_input: &[F], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think compile_program should have public_input and private_input as parameters, because the compiled program shouldn't depend on the future inputs it will run on, if that makes sense
1cb93fe to
bb013ec
Compare
|
@TomWambsgans clarified that the prover is agnostic to whether a deref instruction specifies 2 undefined memory cells. This allows the range check technique to work without the compiler having to know the public/private inputs ahead of time. The runner just needs to distinguish between derefs that are used for the range check and derefs which are not, and ignore UndefinedMemory errors for the former. I rewrote this PR to:
I've pushed my work in progress. Currently, tests are slow because the prover doesn't work with small programs and emits a |
|
The bug |
2cde898 to
c448cd3
Compare
|
I've completed this PR and it's ready for review. I've also edited the parent comment to describe how the range check statement works and what changes this PR makes. Thanks for the help making this possible! |
|
Review in progress, thanks! I will also try to add some logic to the runner: to make 'v < t' work even if m[v] (or m[t - v] are undefined at the time of execution of the range check (and are filled later / or never filled at all). When we will have that, we should be able to use it in the XMSS verification program. Bonus: I also would like to implem the following opti: in case of many consecutive range checks (as it's the case in the encoding for XMSS currently), if |
fccbf1f to
4becd65
Compare
|
I've fixed this PR to make the prover fill in any undefined cells which are ignored by range-check DEREFs. The changes are as such:
|
This pull request implements the
range_checklanguage feature. It allows the programmer to ensure that some expressionvalis less than some constantt. For instance:The above program can be executed and proven as long as
val < 5, but not ifval >= 5.tmust be less than or equal to 2 ** 16.Theory
See section 2.5.3 of minimal_zkVM.pdf for a full explanation of how the technique works.
Approach
Each range check inserts 3 opcodes: deref, add, and deref:
Using DEREF, set
m[fp + i]tom[m[fp + x]].m[fp + x] >= M, we ensure thatm[fp + x] < M.Using ADD, ensure (via constraint-solving):
m[fp + j] + m[m[fp + x]] = (t - 1).Using DEREF, ensure
m[m[fp + j]] = m[fp + k].m[fp + j] >= M, we ensure that(t - 1) - m[fp + x] < M.Auxiliary variables
During compilation, 3 stack slots are reserved for the auxiliary variables i, j, and k.
Modifications to the runner
I modified the DEREF opcode to have a
for_range_checkflag. If the runner encounters a DEREF with this flag set totrue, it will ignore anyUndefinedMemoryerrors, which is intentional.Modifications to the prover
If the prover encounters a DEREF instruction where
m[fp + x] >= Morm[fp + j] >= M, it should not be able to generate a proof. I modified theget_execution_trace()function to defaultvalue_a,value_bandvalue_ctoF::ZEROif their respective address is beyondM, but theCOL_INDEX_MEM_ADDRESS_{A,B,C}column will contain a value beyond M. I also modified theprove_execution()function to return aProveExecutionError::MemoryErrorifbase_memory_indexescontains any oversized index.Tests
To run the tests:
cargo test --release --package lean_prover test_range_check