Stone prover parameters file format
{
"field": "PrimeField0",
"use_extension_field": false,
"stark": {
"fri": {
"fri_step_list": [4, 4, 2],
"last_layer_degree_bound": 64,
"n_queries": 18,
"proof_of_work_bits": 24
},
"log_n_cosets": 4
},
"verifier_friendly_channel_updates": true,
"verifier_friendly_commitment_hash": "poseidon3",
"channel_hash": "poseidon3",
"n_verifier_friendly_commitment_layers": 1000,
"pow_hash": "keccak256",
"commitment_hash": "keccak256_masked160_lsb",
}
Stone prover parameters
Prime field definition
{
"field": "PrimeField0",
"use_extension_field": false,
...
}
Fields field
and use_extension_field
define parameters for generation of
prime field (finite field modulus prime number)
Available values for field field
:
- TestField
- PrimeField0
- PrimeField1
- PrimeField2
- PrimeField3
- PrimeField4
- LongField
- ExtensionLongField
- ExtensionTestField
- ExtensionPrimeField0
PrimeField0
is a STARK compatible field with element size 252 bits. Should be picked for Cairo programs. ExtensionPrimeField0
is also STARK compatible, operations in that field introduce computational overhead in exchange for better security.
use_extension_field
- is a flag that asserts that field selected in field
is an extension field. In other words: it should be set to true
if you picked one of:
ExtensionLongField
, ExtensionTestField
, ExtensionPrimeField0
as a field
value.
STARK and Fast Reed-Solomon IOP of Proximity (FRI)
This section configures parameters of the proof itself.
{
...
"stark": {
"fri": {
"fri_step_list": [4, 4, 2],
"last_layer_degree_bound": 64,
"n_queries": 18,
"proof_of_work_bits": 24
},
"log_n_cosets": 4
},
...
}
n_queries
- amount of checks to be performed against the proof the more queries the higher soundness. In order to achieve the required soundness of the protocol, the query phase is repeated multiple times. For a blowup factor of 2ⁿ, each query roughly contributes n bits of security.
log_n_cosets
- defines the size of the points where polinomial will be calculated (evaluation domain). The bigger the size of the coset the higher soundness FRI have, but also bloats prooving time. Reduce to make prooving faster.
fri
- The FRI protocol is crucial to the soundness of STARK proofs. It reduces the complexity of the proximity proofs generated by STARK and can be fine-tuned to balance performance and security.
fri_step_list
- The FRI step parameters do not affect the soundness of the proof, but they affect the proof length and verification time. By default it is recommended to use [4, 4, 2] value (see below).
As you increase a certain FRI step, more values need to be revealed from the corresponding Merkle tree but the number of Merkle trees reduces. However, the number of values that is revealed is 2^step, so the step cannot be too big. The last layer size plays a similar role - as you increase it you need less Merkle trees but reveal more values. Exact formula for calculation the optimal value is unknown but stone prover developers discovered that the array of size 3 usually provides best results. If the proof is large the recommendation is to start with a number [4] and end with number [2] or [2, 2]. This example defines that the proof size will reduce by a factor of 4 for the first three steps, and by a factor of 2 at the last step. In case you encounter error during the proof generation that looks like:
Fri parameters do not match stark degree bound.
Expected FRI degree from FriParameters: 8192. STARK: 2097152
Please, consult with /helpers/calculate_fri_step_list.py
. This script will generate value for fri_step_list depending on desired FRI degree parameter. This script generates the steps value so that equation:
log₂(last_layer_degree_bound) + ∑fri_step_list = log₂(#steps) + 4
would stand.
last_layer_degree_bound
- Another FRI optimization used to reduce the proof size is to terminate the FRI protocol earlier than when the last layer reaches a constant value. In such case, instead of having the prover send only the constant value of the last layer as a commitment, the prover sends the coefficients of the polynomial representing the last layer instead. This allows the verifier to complete the protocol as before, without the need for commitments (and sending decommitments for field elements in the smaller last layers). In our Alpha version, the FRI commit phase is typically terminated when it reaches a polynomial pⱼ of degree less than 64. The exact number may vary depending on the trace size. With that said last layer degree bound should be 32 or 64
proof_of_work_bits
- (proof_of_work_bits
): Adds (grinding) computational complexity for generating proofs to deter brute-force attacks. As mentioned above, every query adds a certain number of bits to the security (soundness) of the proof. However, it also implies sending more decommitments by the prover which increases proof size. One mechanism to reduce the need for many queries is to increase the cost of generating a false proof by a malicious prover. We achieve this by adding to the above protocol a requirement that following all the commitments made by the prover, it also finds a 256 bit nonce that hashed together with the state of the hash chain results in a predefined template of a required length. The length of the template defines a certain amount of work that the prover must perform before generating the randomness representing the queries. As a result, a malicious prover that attempts to generate favorable queries will need to repeat the grinding process every time that a commitment is changed. On the other hand, an honest prover, only needs to perform grinding once.
For example:
"proof_of_work_bits": 24
Proof optimisation
Important fact: the num of security bits for the stone proof calculated by (n_queries * log_n_cosets) + proof_of_work_bits.
To summarize the above:
n_queries
- If you decrease n_queries, then verification time goes down. Soundness and gets worse, proof size gets less. Can be traded for proof_of_work_bits
or/and log_n_cosets
.
proof_of_work_bits
- If you decrease proof_of_work_bits proof generation time goes down. Soundness gets worse. Can be traded for n_queries (more proof_of_work_bits for less queries).
fri_step_list
- less layers, less proof size, but increased verification time.
log_n_cosets
- decrease to decrease verification time. Can be traded for n_queries. More n_queries
- less log_n_cosets
.
Air verifier parameters
{
...
"verifier_friendly_channel_updates": true,
"n_verifier_friendly_commitment_layers": 1000,
"verifier_friendly_commitment_hash": "poseidon3",
"channel_hash": "poseidon3",
"pow_hash": "keccak256",
"commitment_hash": "keccak256_masked160_lsb",
...
}
Hashes
These parameters are often found in configuration files related to the verifier, and they aim to optimize the verification process.
commitment_hash
- Hash function used for generating commitments, which are crucial for zero-knowledge proofs. Default value: keccak256_masked160_msb
.
channel_hash
- Specifies the input hash function used for transcript channel security. Transcript used for exchanging data between prover and verifier. All queries are communicated over it.
Default value is keccak256
.
verifier_friendly_channel_updates
- If verifier_friendly_channel_updates is true, then the channel initialization is performed by a hash of the verifier friendly hash function (n_verifier_friendly_commitment_layers
layers are being created), and afterwards the channel continues to produce numbers based on the channel_hash function. Otherwise, the channel_hash is used for the entire process. Deafult value is false
.
verifier_friendly_commitment_hash
- Specifies the type of hash function used for the verifier's commitment, optimized for verification. Default value is taken from commitment_hash
.
n_verifier_friendly_commitment_layers
- defines the number of layers in transcript that have the verifier_friednly_commitment_hash
, the rest of the layers (bigger ones) are defined by commitment_hash
- This is basically tradeoff, you can increase the number of layers that use zk friendly hash function (eg poseidon) to make verification cheaper, but proving will be longer
pow_hash
- Defines the hash used for proof-of-work, ensuring security in proof generation. Default value is blake256
. This hash function must produce 256 bit long digest (can't be poseidon)
commitment_hash
, channel_hash
, verifier_friendly_channel_updates
, verifier_friendly_commitment_hash
, verifier_friendly_commitment_hash
, pow_hash
- are all different hash functions. Available set of hash function names can be defined as follows:
- "keccak256" - Keccak hash with 256 bit digest.
- "blake2s256" - Blake hash with 256 bit digest.
- "pedersen" - Pedersen Keccak hash with 256 bit digest.
- "poseidon3" - Poseidon3 Keccak hash with 252 bit digest.
- "keccak256_masked_160_msb" - This is similar to
keccak256
but the size of digest is truncated to 160 bits, 96 least significant bits are thrown away. - "blake2s256_masked_160_msb" - This is similar to
blake2s256
but the size of digest is truncated to 160 bits, 96 least significant bits are thrown away. - "blake2s256_masked_248_lsb" - This is similar to
blake2s256
but the size of digest is truncated to 248 bits, 8 most significant bits are thrown away. - "keccak256_masked_160_lsb" - This is similar to
keccak256
but the size of digest is truncated to 248 bits, 96 most significant bits are thrown away.
Stone prover configuration file
{
"cached_lde_config": {
"store_full_lde": false,
"use_fft_for_eval": false
},
"constraint_polynomial_task_size": 256,
"n_out_of_memory_merkle_layers": 1,
"table_prover_n_tasks_per_segment": 32
}
Stone prover configuration
LDE
- The low degree extension() is a polynomial of degree n
resulting from
interpolating n
+ 1 data points.
store_full_lde
- Controls a Memory/Performance tradeoff. Setting this
value to false, reduces the memory consumption by recomputing the LDE when
needed instead of storing it. Obviously recomputing will increase computational
costs.
use_fft_for_eval
- Setting this value to true will recompute the LDE (using
FFT on the entire coset) when evaluating at a point. Otherwise, only the
evaluations required will be computed (using horner evaluation). This value has
no effect when store_full_lde
is true.
table_prover_n_tasks_per_segment
- Controls The number of tasks used to
commit to a segment in the table prover. Table prover used as a part of FRI
verification process.
constraint_polynomial_task_size
- Evaluation of composition polynomial on
the coset is split to different tasks of size constraint_polynomial_task_size
each to allow multithreading. The larger the task size the lower the amortized
threading overhead but this can also affect the fragmentation effect in case
the number of tasks doesn't divide the coset by a multiple of the number of
threads in the thread pool.
n_out_of_memory_merkle_layers
- Number of merkle layer that are not stored
in memory but instead recalculated when required by decommitment request. When
n_out_of_memory_merkle_layers
is 0 it means that all the data is stored in the
merkle tree. When n_out_of_memory_merkle_layers
is 1 it means that the layer
of the leaves are not stored in memory and so on.