Skip to content
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

Add solidity verifier of the nova+cyclefold #87

Merged
merged 30 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
08f8bc5
Add solidity verifier of the nova+cyclefold, and add method to prepar…
arnaucube Mar 21, 2024
c950dba
chore: adding comments linking to the contract's signature
dmpierre Mar 27, 2024
443c78a
chore: update .gitignore
dmpierre Mar 27, 2024
340da08
chore: add num-bigint as dev dependency
dmpierre Mar 27, 2024
ee0214e
fix: work with abs path for storing generated sol code
dmpierre Mar 27, 2024
888b7f6
chore: update comment
dmpierre Mar 29, 2024
dc263d2
feat: solidity verifier working on single and multi-input circuits
dmpierre Mar 29, 2024
86498af
feat: multi-input folding verification working + fixing encoding of a…
dmpierre Mar 29, 2024
aba6574
chore: make bigint a dependency
dmpierre Apr 1, 2024
9226054
refactor: import utils functions from utils.rs and make them availabl…
dmpierre Apr 1, 2024
bee2233
chore: make utils and evm available publicly
dmpierre Apr 1, 2024
cc6e2f7
fix: pub mod instead
dmpierre Apr 1, 2024
f7cc446
chore: make relevant method public and add `get_decider_template_for_…
dmpierre Apr 1, 2024
6e5c130
solidity-verifiers: move tests to their corresponding files
arnaucube Apr 2, 2024
525e460
small update: Cyclefold -> CycleFold at the missing places
arnaucube Apr 2, 2024
71b5eba
abstract nova-cyclefold solidity verifiers tests to avoid code duplic…
arnaucube Apr 2, 2024
8a1327c
small polish after rebase to last main branch changes
arnaucube Apr 5, 2024
b5f3c24
rm unneeded Option for KZGData::g1_crs_batch_points
arnaucube Apr 8, 2024
13d528b
add checks modifying z_0 & z_i to nova_cyclefold_solidity_verifier test
arnaucube Apr 8, 2024
2ff06c0
add light-test feature to decider_eth_circuit to use it in solidity-v…
arnaucube Apr 9, 2024
2917f0d
solidity-verifiers: groth16 template: port the fix from https://githu…
arnaucube Apr 9, 2024
b113781
add print warning msg for light-test in DeciderEthCircuit
arnaucube Apr 12, 2024
2aeaa2b
solidity-verifiers: update limbs logic to nonnative last version, par…
arnaucube Apr 16, 2024
641f9a1
move solidity constants into template constants for auto compute of p…
arnaucube Apr 16, 2024
ad6bbfc
polishing
arnaucube Apr 16, 2024
9ae84fb
revm use only needed feature
arnaucube Apr 16, 2024
bc42865
nova_cyclefold_decider.sol header
arnaucube Apr 16, 2024
fc84ff0
rearrange test helpers position, add error for min number of steps
arnaucube Apr 23, 2024
96eef58
in solidity-verifiers: 'data'->'vk/verifier key'
arnaucube Apr 23, 2024
87d3731
add From for NovaCycleFoldVerifierKey from original vks to simplify d…
arnaucube Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ jobs:
- name: Build
# This build will be reused by nextest,
# and also checks (--all-targets) that benches don't bit-rot
run: cargo build --release --all-targets --no-default-features --features "${{ matrix.feature }}"
run: cargo build --release --all-targets --no-default-features --features "light-test,${{ matrix.feature }}"
- name: Test
run: |
cargo nextest run --profile ci --release --workspace --no-default-features --features "${{ matrix.feature }}"
cargo nextest run --profile ci --release --workspace --no-default-features --features "light-test,${{ matrix.feature }}"
- name: Doctests # nextest does not support doc tests
run: |
cargo test --doc
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/target
Cargo.lock

# Circom generated files
folding-schemes/src/frontend/circom/test_folder/cubic_circuit.r1cs
folding-schemes/src/frontend/circom/test_folder/cubic_circuit_js/
Expand Down
35 changes: 6 additions & 29 deletions cli/README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,6 @@
# Solidity Verifiers CLI
_____ ______ ______ ______ ______ ______ ______
| |__| || |__| || |__| || |__| || |__| || |__| || |__| |
| () || () || () || () || () || () || () |
|______||______||______||______||______||______||______|
______ ______
| |__| | ____ _ _ _ _ _ | |__| |
| () | / ___| ___ | (_) __| (_) |_ _ _ | () |
|______| \___ \ / _ \| | |/ _` | | __| | | | |______|
______ ___) | (_) | | | (_| | | |_| |_| | ______
| |__| | |____/ \___/|_|_|\__,_|_|\__|\__, | | |__| |
| () | __ __ _ __ _ |___/ | () |
|______| \ \ / /__ _ __(_)/ _(_) ___ _ __ |______|
______ \ \ / / _ \ '__| | |_| |/ _ \ '__| ______
| |__| | \ V / __/ | | | _| | __/ | | |__| |
| () | \_/ \___|_| |_|_| |_|\___|_| | () |
|______| |______|
______ ______ ______ ______ ______ ______ ______
| |__| || |__| || |__| || |__| || |__| || |__| || |__| |
| () || () || () || () || () || () || () |
|______||______||______||______||______||______||______|

Welcome to Solidity Verifiers CLI, a Command-Line Interface (CLI) tool designed to simplify the generation of Solidity smart contracts that verify proofs of Zero Knowledge cryptographic protocols. This tool is developed by the collaborative efforts of the PSE (Privacy & Scaling Explorations) and 0XPARC teams.
Solidity Verifiers CLI is a Command-Line Interface (CLI) tool to generate the Solidity smart contracts that verify proofs of Zero Knowledge cryptographic protocols. This tool is developed by the collaborative efforts of the PSE (Privacy & Scaling Explorations) and 0xPARC teams.

Solidity Verifiers CLI is released under the MIT license, but notice that the Solidity template for the Groth16 verification has GPL-3.0 license, hence the generated Solidity verifiers that use the Groth16 template will have that license too.

Expand All @@ -34,7 +14,7 @@ Solidity Verifier currently supports the generation of Solidity smart contracts

- **KZG:**
- Uses the Kate-Zaverucha-Goldberg polynomial commitment scheme.
- Example credit: [weijiekoh - KZG10 Verifier Contract](https://github.com/weijiekoh/libkzg/blob/master/sol/KZGVerifier.sol)
- Template credit: [weijiekoh - KZG10 Verifier Contract](https://github.com/weijiekoh/libkzg/blob/master/sol/KZGVerifier.sol)

- **Nova + CycleFold Decider:**
- Implements the decider circuit verification for the Nova proof system in conjunction with the CycleFold protocol optimization.
Expand All @@ -43,19 +23,19 @@ Solidity Verifier currently supports the generation of Solidity smart contracts
## Usage

```bash
solidity-verifiers-cli [OPTIONS] -p <PROTOCOL> -d <PROTOCOL_DATA> -o <OUTPUT_PATH>
solidity-verifiers-cli [OPTIONS] -p <PROTOCOL> -k <PROTOCOL_VK> -o <OUTPUT_PATH>
```

A real use case (which was used to test the tool itself):
`solidity-verifiers-cli -p groth16 -d ./solidity-verifiers/assets/G16_test_vk_data`
This would generate a Groth16 verifier contract for the given G16 data (which consists on the G16_Vkey only) and store this contract in `$pwd`.
`solidity-verifiers-cli -p groth16 -k ./solidity-verifiers/assets/G16_test_vk`
This would generate a Groth16 verifier contract for the given G16 verifier key (which consists on the G16_Vk only) and store this contract in `$pwd`.

### Options:
-v, --verbose: Increase logging verbosity
-q, --quiet: Decrease logging verbosity
-p, --protocol <PROTOCOL>: Selects the protocol for which to generate the Decider circuit Solidity Verifier (possible values: groth16, kzg, nova-cyclefold)
-o, --out <OUT>: Sets the output path for all generated artifacts
-d, --protocol-data <PROTOCOL_DATA>: Sets the input path for the file containing all the data required by the chosen protocol for verification contract generation
-k, --protocol-vk <PROTOCOL_VK>: Sets the input path for the file containing the verifier key required by the protocol chosen such that the verification contract can be generated.
--pragma <PRAGMA>: Selects the Solidity compiler version to be set in the Solidity Verifier contract artifact
-h, --help: Print help (see a summary with '-h')
-V, --version: Print version
Expand All @@ -66,6 +46,3 @@ Solidity Verifier CLI is released under the MIT license, but notice that the Sol
## Contributing
Feel free to explore, use, and contribute to Solidity Verifiers CLI as we strive to enhance privacy and scalability in the blockchain space!
We welcome contributions to Solidity Verifiers CLI! If you encounter any issues, have feature requests, or want to contribute to the codebase, please check out the GitHub repository and follow the guidelines outlined in the contributing documentation.



4 changes: 2 additions & 2 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ fn main() {
// Fetch the exact protocol for which we need to generate the Decider verifier contract.
let protocol = cli.protocol;
// Fetch the protocol data passed by the user from the file.
let protocol_data = std::fs::read(cli.protocol_data).unwrap();
let protocol_vk = std::fs::read(cli.protocol_vk).unwrap();

// Generate the Solidity Verifier contract for the selected protocol with the given data.
create_or_open_then_write(
&out_path,
&protocol.render(&protocol_data, cli.pragma).unwrap(),
&protocol.render(&protocol_vk, cli.pragma).unwrap(),
)
.unwrap();
}
37 changes: 20 additions & 17 deletions cli/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use ark_serialize::SerializationError;
use clap::{Parser, ValueEnum};
use solidity_verifiers::{Groth16Data, KzgData, NovaCyclefoldData, ProtocolData};
use solidity_verifiers::{
Groth16VerifierKey, KZG10VerifierKey, NovaCycleFoldVerifierKey, ProtocolVerifierKey,
};
use std::{env, fmt::Display, path::PathBuf};

fn get_default_out_path() -> PathBuf {
Expand All @@ -13,7 +15,7 @@ fn get_default_out_path() -> PathBuf {
pub(crate) enum Protocol {
Groth16,
Kzg,
NovaCyclefold,
NovaCycleFold,
}

impl Display for Protocol {
Expand All @@ -22,7 +24,7 @@ impl Display for Protocol {
}
}

// Would be nice to link this to the `Template` or `ProtocolData` traits.
// Would be nice to link this to the `Template` or `ProtocolVerifierKey` traits.
// Sadly, this requires Boxing with `dyn` or similar which would complicate the code more than is actually required.
impl Protocol {
pub(crate) fn render(
Expand All @@ -31,19 +33,20 @@ impl Protocol {
pragma: Option<String>,
) -> Result<Vec<u8>, SerializationError> {
match self {
Self::Groth16 => {
Ok(Groth16Data::deserialize_protocol_data(data)?.render_as_template(pragma))
}

Self::Kzg => Ok(KzgData::deserialize_protocol_data(data)?.render_as_template(pragma)),
Self::NovaCyclefold => {
Ok(NovaCyclefoldData::deserialize_protocol_data(data)?.render_as_template(pragma))
}
Self::Groth16 => Ok(Groth16VerifierKey::deserialize_protocol_verifier_key(data)?
.render_as_template(pragma)),

Self::Kzg => Ok(KZG10VerifierKey::deserialize_protocol_verifier_key(data)?
.render_as_template(pragma)),
Self::NovaCycleFold => Ok(NovaCycleFoldVerifierKey::deserialize_protocol_verifier_key(
data,
)?
.render_as_template(pragma)),
}
}
}

const ABOUT: &str = "A Command-Line Interface (CLI) tool designed to simplify the generation of Solidity smart contracts that verify proofs of Zero Knowledge cryptographic protocols.
const ABOUT: &str = "A Command-Line Interface (CLI) tool to generate the Solidity smart contracts that verify proofs of Zero Knowledge cryptographic protocols.
";

const LONG_ABOUT: &str = "
Expand All @@ -68,7 +71,7 @@ const LONG_ABOUT: &str = "
| () || () || () || () || () || () || () |
|______||______||______||______||______||______||______|

Welcome to Solidity Verifiers CLI, a Command-Line Interface (CLI) tool designed to simplify the generation of Solidity smart contracts that verify proofs of Zero Knowledge cryptographic protocols. This tool is developed by the collaborative efforts of the PSE (Privacy & Scaling Explorations) and 0XPARC teams.
Welcome to Solidity Verifiers CLI, a Command-Line Interface (CLI) tool designed to simplify the generation of Solidity smart contracts that verify proofs of Zero Knowledge cryptographic protocols. This tool is developed by the collaborative efforts of the PSE (Privacy & Scaling Explorations) and 0xPARC teams.

Solidity Verifiers CLI is released under the MIT license, but notice that the Solidity template for the Groth16 verification has GPL-3.0 license, hence the generated Solidity verifiers that use the Groth16 template will have that license too.

Expand All @@ -84,7 +87,7 @@ Solidity Verifier currently supports the generation of Solidity smart contracts
Implements the decider circuit verification for the Nova proof system in conjunction with the CycleFold protocol optimization.
";
#[derive(Debug, Parser)]
#[command(author = "0XPARC & PSE", version, about = ABOUT, long_about = Some(LONG_ABOUT))]
#[command(author = "0xPARC & PSE", version, about = ABOUT, long_about = Some(LONG_ABOUT))]
#[command(propagate_version = true)]
/// A tool to create Solidity Contracts which act as verifiers for the major Folding Schemes implemented
/// within the `sonobe` repo.
Expand All @@ -100,9 +103,9 @@ pub(crate) struct Cli {
/// Sets the output path for all the artifacts generated by the command.
pub out: PathBuf,

#[arg(short = 'd', long)]
/// Sets the input path for the file containing all the data required by the protocol chosen such that the verification contract can be generated.
pub protocol_data: PathBuf,
#[arg(short = 'k', long)]
/// Sets the input path for the file containing the verifier key required by the protocol chosen such that the verification contract can be generated.
pub protocol_vk: PathBuf,

/// Selects the Solidity compiler version to be set in the Solidity Verifier contract artifact.
#[arg(long, default_value=None)]
Expand Down
4 changes: 3 additions & 1 deletion folding-schemes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ rayon = "1.7.0"
num-bigint = "0.4"
num-integer = "0.1"
color-eyre = "=0.6.2"
ark-bn254 = {version="0.4.0"}
ark-groth16 = { version = "^0.4.0" }

# tmp imports for espresso's sumcheck
espresso_subroutines = {git="https://github.com/EspressoSystems/hyperplonk", package="subroutines"}
Expand All @@ -29,13 +31,13 @@ ark-pallas = {version="0.4.0", features=["r1cs"]}
ark-vesta = {version="0.4.0", features=["r1cs"]}
ark-bn254 = {version="0.4.0", features=["r1cs"]}
ark-grumpkin = {version="0.4.0", features=["r1cs"]}
ark-groth16 = { version = "^0.4.0" }
rand = "0.8.5"
tracing = { version = "0.1", default-features = false, features = [ "attributes" ] }
tracing-subscriber = { version = "0.2" }

[features]
default = ["parallel"]
light-test = []

parallel = [
"ark-std/parallel",
Expand Down
2 changes: 1 addition & 1 deletion folding-schemes/src/folding/circuits/nonnative/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ impl<F: PrimeField> ToBitsGadget<F> for LimbVar<F> {
pub struct NonNativeUintVar<F: PrimeField>(pub Vec<LimbVar<F>>);

impl<F: PrimeField> NonNativeUintVar<F> {
const fn bits_per_limb() -> usize {
pub const fn bits_per_limb() -> usize {
assert!(F::MODULUS_BIT_SIZE > 250);
// For a `F` with order > 250 bits, 55 is chosen for optimizing the most
// expensive part `Az∘Bz` when checking the R1CS relation for CycleFold.
Expand Down
2 changes: 1 addition & 1 deletion folding-schemes/src/folding/hypernova/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ pub mod tests {
/// - M(01) = 4*eq_00(r) + 3*eq_10(r) + 9*eq_01(r) + 2*eq_11(r)
/// - M(11) = 4*eq_00(r) + 2*eq_10(r) + 2*eq_01(r) + 0*eq_11(r)
///
/// This is used by Hypernova in LCCCS to perform a verifier-chosen random linear combination between the columns
/// This is used by HyperNova in LCCCS to perform a verifier-chosen random linear combination between the columns
/// of the matrix and the z vector. This technique is also used extensively in "An Algebraic Framework for
/// Universal and Updatable SNARKs".
#[test]
Expand Down
92 changes: 86 additions & 6 deletions folding-schemes/src/folding/nova/decider_eth.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
/// This file implements the onchain (Ethereum's EVM) decider.
use ark_bn254::Bn254;
use ark_crypto_primitives::sponge::Absorb;
use ark_ec::{CurveGroup, Group};
use ark_ff::PrimeField;
use ark_ec::{AffineRepr, CurveGroup, Group};
use ark_ff::{BigInteger, PrimeField};
use ark_groth16::Groth16;
use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar, ToConstraintFieldGadget};
use ark_snark::SNARK;
use ark_std::rand::{CryptoRng, RngCore};
use ark_std::Zero;
use ark_std::{One, Zero};
use core::marker::PhantomData;

pub use super::decider_eth_circuit::{DeciderEthCircuit, KZGChallengesGadget};
use super::{circuits::CF2, nifs::NIFS, CommittedInstance, Nova};
use crate::commitment::{
kzg::Proof as KZGProof, pedersen::Params as PedersenParams, CommitmentScheme,
kzg::{Proof as KZGProof, KZG},
pedersen::Params as PedersenParams,
CommitmentScheme,
};
use crate::folding::circuits::nonnative::affine::NonNativeAffineVar;
use crate::frontend::FCircuit;
Expand Down Expand Up @@ -143,8 +147,12 @@ where
z_i: Vec<C1::ScalarField>,
running_instance: &Self::CommittedInstance,
incoming_instance: &Self::CommittedInstance,
proof: Self::Proof,
proof: &Self::Proof,
) -> Result<bool, Error> {
if i <= C1::ScalarField::one() {
return Err(Error::NotEnoughSteps);
}

let (snark_vk, cs_vk): (S::VerifyingKey, CS1::VerifierParams) = vp;

// compute U = U_{d+1}= NIFS.V(U_d, u_d, cmT)
Expand Down Expand Up @@ -199,6 +207,78 @@ where
}
}

/// Prepares solidity calldata for calling the NovaDecider contract
pub fn prepare_calldata(
function_signature_check: [u8; 4],
i: ark_bn254::Fr,
z_0: Vec<ark_bn254::Fr>,
z_i: Vec<ark_bn254::Fr>,
running_instance: &CommittedInstance<ark_bn254::G1Projective>,
incoming_instance: &CommittedInstance<ark_bn254::G1Projective>,
proof: Proof<ark_bn254::G1Projective, KZG<'static, Bn254>, Groth16<Bn254>>,
) -> Result<Vec<u8>, Error> {
Ok(vec![
function_signature_check.to_vec(),
i.into_bigint().to_bytes_be(), // i
z_0.iter()
.flat_map(|v| v.into_bigint().to_bytes_be())
.collect::<Vec<u8>>(), // z_0
z_i.iter()
.flat_map(|v| v.into_bigint().to_bytes_be())
.collect::<Vec<u8>>(), // z_i
point_to_eth_format(running_instance.cmW.into_affine())?, // U_i_cmW
point_to_eth_format(running_instance.cmE.into_affine())?, // U_i_cmE
running_instance.u.into_bigint().to_bytes_be(), // U_i_u
incoming_instance.u.into_bigint().to_bytes_be(), // u_i_u
proof.r.into_bigint().to_bytes_be(), // r
running_instance
.x
.iter()
.flat_map(|v| v.into_bigint().to_bytes_be())
.collect::<Vec<u8>>(), // U_i_x
point_to_eth_format(incoming_instance.cmW.into_affine())?, // u_i_cmW
incoming_instance
.x
.iter()
.flat_map(|v| v.into_bigint().to_bytes_be())
.collect::<Vec<u8>>(), // u_i_x
point_to_eth_format(proof.cmT.into_affine())?, // cmT
point_to_eth_format(proof.snark_proof.a)?, // pA
point2_to_eth_format(proof.snark_proof.b)?, // pB
point_to_eth_format(proof.snark_proof.c)?, // pC
proof.kzg_challenges[0].into_bigint().to_bytes_be(), // challenge_W
proof.kzg_challenges[1].into_bigint().to_bytes_be(), // challenge_E
proof.kzg_proofs[0].eval.into_bigint().to_bytes_be(), // eval W
proof.kzg_proofs[1].eval.into_bigint().to_bytes_be(), // eval E
point_to_eth_format(proof.kzg_proofs[0].proof.into_affine())?, // W kzg_proof
point_to_eth_format(proof.kzg_proofs[1].proof.into_affine())?, // E kzg_proof
]
.concat())
}

fn point_to_eth_format<C: AffineRepr>(p: C) -> Result<Vec<u8>, Error>
where
C::BaseField: PrimeField,
{
// the encoding of the additive identity is [0, 0] on the EVM
let zero_point = (&C::BaseField::zero(), &C::BaseField::zero());
let (x, y) = p.xy().unwrap_or(zero_point);

Ok([x.into_bigint().to_bytes_be(), y.into_bigint().to_bytes_be()].concat())
}
fn point2_to_eth_format(p: ark_bn254::G2Affine) -> Result<Vec<u8>, Error> {
let zero_point = (&ark_bn254::Fq2::zero(), &ark_bn254::Fq2::zero());
let (x, y) = p.xy().unwrap_or(zero_point);

Ok([
x.c1.into_bigint().to_bytes_be(),
x.c0.into_bigint().to_bytes_be(),
y.c1.into_bigint().to_bytes_be(),
y.c0.into_bigint().to_bytes_be(),
]
.concat())
}

#[cfg(test)]
pub mod tests {
use super::*;
Expand Down Expand Up @@ -298,7 +378,7 @@ pub mod tests {
let start = Instant::now();
let decider_vp = (g16_vk, kzg_vk);
let verified = DECIDER::verify(
decider_vp, nova.i, nova.z_0, nova.z_i, &nova.U_i, &nova.u_i, proof,
decider_vp, nova.i, nova.z_0, nova.z_i, &nova.U_i, &nova.u_i, &proof,
)
.unwrap();
assert!(verified);
Expand Down
8 changes: 6 additions & 2 deletions folding-schemes/src/folding/nova/decider_eth_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,14 @@ where
.hash(&crh_params, i.clone(), z_0.clone(), z_i.clone())?;
(u_i.x[0]).enforce_equal(&u_i_x)?;

#[cfg(feature = "light-test")]
println!("[WARNING]: Running with the 'light-test' feature, skipping the big part of the DeciderEthCircuit.\n Only for testing purposes.");

// The following two checks (and their respective allocations) are disabled for normal
// tests since they take several millions of constraints and would take several minutes
// (and RAM) to run the test.
#[cfg(not(test))]
// (and RAM) to run the test. It is active by default, and not active only when
// 'light-test' feature is used.
#[cfg(not(feature = "light-test"))]
{
// imports here instead of at the top of the file, so we avoid having multiple
// `#[cfg(not(test))]`
Expand Down
2 changes: 1 addition & 1 deletion folding-schemes/src/folding/protogalaxy/folding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ fn pow_i<F: PrimeField>(i: usize, betas: &Vec<F>) -> F {

/// calculates F[x] using the optimized binary-tree technique
/// described in Claim 4.4
/// of [Protogalaxy](https://eprint.iacr.org/2023/1106.pdf)
/// of [ProtoGalaxy](https://eprint.iacr.org/2023/1106.pdf)
fn calc_f_from_btree<F: PrimeField>(
fw: &[F],
betas: &[F],
Expand Down
Loading
Loading