-
Notifications
You must be signed in to change notification settings - Fork 50
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
Implement hints documentation #378
Changes from all commits
1b0181a
ff502a6
185d0b8
e464724
717f14a
64bdf7e
659b0c2
a662c93
ecad69c
9768dda
8d60a57
e22e40a
952696f
3659651
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,138 @@ | |
sidebar_position: 3 | ||
--- | ||
|
||
# Hints | ||
# Hint | ||
## HINTS IN CAIRO VIRTUAL MACHINE | ||
Hints in Cairo are pieces of Python code only executed by the sequencer and are not included in the bytecode. They instruct the prover on how to handle nondeterministic instructions. These nondeterministic instructions are programs that have different outcomes at execution. | ||
Hints are guides that developers can provide to the Cairo virtual machine to optimize execution or provide additional information about the program. These hints help improve performance or help the VM make better decisions during the execution of programs. | ||
|
||
Below are some Cairo code with hints: | ||
|
||
```cairo | ||
[ap] = 25, ap++; | ||
%{ | ||
import math | ||
memory[ap] = int(math.sqrt(memory[ap - 1])) | ||
%} | ||
[ap - 1] = [ap] * [ap], ap++; | ||
``` | ||
|
||
|
||
```cairo | ||
func main() { | ||
%{ memory[ap] = program_input['secret'] %} | ||
[ap] = [ap], ap++; | ||
ret; | ||
} | ||
``` | ||
|
||
|
||
|
||
### WHY HINTS RUN ON SEQUENCERS/ PROVERS AND NOT VERIFIERS | ||
|
||
The verifier in Cairo is responsible for ensuring that a program attaches safety and accuracy features. It checks that the program satisfies limitations such as memory safety, type safety, and functional correctness. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not true, the verifier doesn't do this. Please, let us not put anything which is not right. As a rule of a thumb if you don't know about it then don't write it. Let's discuss first if it is true or not. We have community calls every Wednesday if you want to pop in and ask all questions you might have. |
||
|
||
Sequencers are the leads that produces blocks by executing transaction and updating the blockchain state. | ||
During the proof generation process, the prover uses hints to generate additional constraints or assumptions about the program's behavior, which makes part of the proof sent to the verifier for verification. In the Cairo VM, hints are sorted out during different stages of the compilation and execution process by the sequencer. However, they are not directly involved in the verification stage. Hints are primarily for performance optimization. | ||
|
||
The key is the implementation of relevant and accurate hints that assist the prover or sequencers in their respective tasks. | ||
|
||
Example: | ||
The *'random'* instruction generates a random number, which can be different each time of instruction execution. The verifier cannot implement these instructions, as it would require access to nondeterministic information, which would beat the purpose of the zero-knowledge proof. | ||
Comment on lines
+41
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this random instruction exists |
||
To solve this problem, Cairo uses hints to instruct the prover on how to handle nondeterministic instructions. The prover will execute the nondeterministic instructions and provide the verifier with enough information to check whether or not the program is accurate without revealing any sensitive information. | ||
Example: | ||
Let's consider a Cairo function that calculates the factorial of a given input *`n`*: | ||
|
||
```Cairo | ||
@public | ||
func factorial(n : felt) -> (result : felt): | ||
if n <= 1: | ||
result := 1 | ||
else: | ||
result := n * factorial(n - 1) | ||
``` | ||
|
||
In this code, the hint *@public* indicates that the *`n`* factorial should be publicly available in the Cairo program. | ||
The provers/sequencers will utilize the hint to generate a proof or sequence of instructions for the function to ensure maximum optimization. The verifier will check that the generated proof or sequence of instructions has correctly calculated the factorial of the input *`n`* or any other specification is satisfied. | ||
|
||
## IMPLEMENTING HINTS IN CAIRO VIRTUAL MACHINE | ||
|
||
In Cairo Virtual Machine, hints are accepted and recognized by its code. | ||
Hints are implemented using the *%{...%}* syntax, which allows you to insert Python code that is only executed by the prover. When implementing hints, the *'variable naming convention'* should be considered. The method to handle specific hints should be outlined like this; *'create hintName Hinter'*. Hints should be grouped by functionality in Cairo programs. The structure returned should implement the interface. Implementing the hint means you have to write code in Go that has the same behavior as the code of the hint in Python. Unit tests are added to check if the behavior of your code is correct. | ||
|
||
Examples of how to implement a hint in cairo: | ||
|
||
``` cairo | ||
from starkware.cairo.common.hints import Hint | ||
|
||
class FactorialHint(Hint): | ||
def __init__(self, n): | ||
self.n = n | ||
|
||
def process(self, cairo_ctx): | ||
result = 1 | ||
for i in range(2, self.n + 1): | ||
result *= i | ||
return [result] | ||
|
||
//Usage | ||
[ap] = 5, ap++; | ||
%{ | ||
hint_processor = FactorialHint(memory[ap - 1]) | ||
memory[ap] = cairo_runner.run_from_entrypoint( | ||
entrypoint, | ||
[2, (2,0)], | ||
False, | ||
vm, | ||
hint_processor | ||
)[0]; | ||
%} | ||
[ap - 1] = [ap] * [ap], ap++; | ||
|
||
``` | ||
|
||
```cairo | ||
from starkware.cairo.common.math import assert_nn_le | ||
|
||
struct KeyValue { | ||
key: felt, | ||
value: felt, | ||
} | ||
|
||
struct HintResult { | ||
idx: felt, | ||
} | ||
|
||
func get_value_by_key{range_check_ptr}( | ||
list: KeyValue*, size, key | ||
) -> (value: felt) { | ||
alloc_locals; | ||
local idx; | ||
local hint_result: HintResult; | ||
|
||
%{ | ||
# Define the hint function | ||
def hint_get_index_by_key(list, size, key): | ||
for i in range(size): | ||
if list[i].key == key: | ||
return HintResult(i) | ||
raise ValueError("Key not found") | ||
|
||
# Call the hint function and store the result in memory | ||
hint_result = hint_get_index_by_key(list, size, key) | ||
memory[ap] = hint_result.idx | ||
ap += 1 | ||
%} | ||
|
||
# Load the result of the hint function from memory | ||
hint_result = memory[ap - 1]; | ||
ap -= 1; | ||
|
||
assert_nn_le(hint_result.idx, size); | ||
return list[hint_result.idx].value; | ||
} | ||
|
||
``` | ||
|
||
|
||
|
||
There are several hints, explain each of them here. How they interact with the VM and affects it. |
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.
This part is partially correct, I understand is a complex subject and that you want to explain the "why" of the hints. Let's reduce this paragraph to something simpler: "Hints are used to help the Virtual Machine determine the next path of execution it should take"