Skip to content

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.