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

First Release #1

Merged
merged 48 commits into from
Jul 27, 2021
Merged
Show file tree
Hide file tree
Changes from 40 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
acd3ec5
add direct ldt
tsunrise May 4, 2021
fb986e7
add test direct ldt + one bug fix
tsunrise May 4, 2021
2b71f91
add FRI parameter
tsunrise May 5, 2021
0ced4d8
add coset support for directLDT
tsunrise May 6, 2021
0ba8381
coset consistency check with r1cs_std
tsunrise May 6, 2021
d9fc4c2
direct LDT
tsunrise May 16, 2021
115c260
work
tsunrise May 16, 2021
e4b1053
work
tsunrise May 17, 2021
7df22aa
add prover sanity test
tsunrise May 17, 2021
0e3b085
add prover sanity test
tsunrise May 17, 2021
72b58e3
add prover sanity test
tsunrise May 17, 2021
f5d915e
verifier midpoint
tsunrise May 19, 2021
f7a4ff8
native code for query_pos_to_cosets (not tested yet)
tsunrise May 19, 2021
4ab51f2
add `query_coset` code
tsunrise May 20, 2021
f23b5d7
FRI verifier beta
tsunrise May 21, 2021
b24f908
fri verifier almost finished
tsunrise May 22, 2021
2ea701c
fri verifier beta
tsunrise May 22, 2021
a16cba8
CI
tsunrise May 22, 2021
e720ffa
Update ci.yml
tsunrise May 22, 2021
8384e2b
update test
tsunrise May 22, 2021
3a7c1db
nostd and fmt
tsunrise May 22, 2021
e25cff7
fix no-std 2
tsunrise May 22, 2021
f720e09
fix no-std 3
tsunrise May 22, 2021
7017e84
fix no-std 3.1
tsunrise May 22, 2021
c164e5f
adapt efficient prover from libiop
tsunrise May 23, 2021
af48adf
adapt efficient prover from libiop
tsunrise May 23, 2021
a6cb88d
better support for final polynomial
tsunrise May 25, 2021
a810c4d
add directLDT constraints
tsunrise May 25, 2021
c3fe45d
add tracing
tsunrise May 25, 2021
92fc421
constraints skeleton
tsunrise May 27, 2021
04ccd5d
add degree bound for directLDT constraints
tsunrise May 29, 2021
119b802
tweak
tsunrise May 29, 2021
5703052
add batch operations
tsunrise May 29, 2021
30c9d9e
move `fold_domain` to `domain` module
tsunrise May 30, 2021
84ac478
add comment
tsunrise May 31, 2021
bdfed33
prepare query constraints
tsunrise Jun 4, 2021
8b684dd
finish up FRI constraints
tsunrise Jun 6, 2021
9ea96a8
tweak
tsunrise Jun 6, 2021
2a2d3df
tweak
tsunrise Jun 8, 2021
fe80245
Update ci.yml
tsunrise Jun 8, 2021
b406751
update README
tsunrise Jun 8, 2021
1149c0a
Update README.md
tsunrise Jun 8, 2021
e03b76c
Update README.md
tsunrise Jun 9, 2021
6dfae44
tweak
tsunrise Jun 9, 2021
a4a74a9
update docs and names
tsunrise Jul 2, 2021
676f9ff
update docs and names
tsunrise Jul 20, 2021
527d891
tweak
tsunrise Jul 22, 2021
c0e296a
move one test
tsunrise Jul 24, 2021
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
31 changes: 7 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ on:
pull_request:
push:
branches:
- master
- main
env:
RUST_BACKTRACE: 1

Expand Down Expand Up @@ -50,14 +50,6 @@ jobs:
toolchain: ${{ matrix.rust }}
override: true

- uses: actions/cache@v2
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: Check examples
uses: actions-rs/cargo@v1
with:
Expand All @@ -75,16 +67,14 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: check
args: --all-features --examples --workspace --benches
args: --all-features --examples --all --benches
if: matrix.rust == 'nightly'

- name: Test
uses: actions-rs/cargo@v1
with:
command: test
args: "--workspace \
--all-features \
--exclude ark-poly-benches"
args: --release

check_no_std:
name: Check no_std
Expand Down Expand Up @@ -115,14 +105,7 @@ jobs:
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

- name: check
uses: actions-rs/cargo@v1
with:
command: check
args: --examples --workspace --exclude ark-poly-benches --target thumbv6m-none-eabi

- name: build
uses: actions-rs/cargo@v1
with:
command: build
args: --workspace --exclude ark-poly-benches --target thumbv6m-none-eabi
- name: ldt
run: |
cargo build --no-default-features --target aarch64-unknown-none
cargo check --examples --no-default-features --target aarch64-unknown-none
25 changes: 25 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "ark-ldt"
version = "0.1.0"
authors = ["arkworks contributors"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
ark-ff = { version = "^0.3.0", default-features = false }
ark-std = { version = "^0.3.0", default-features = false }
ark-relations = { version = "^0.3.0", default-features = false }
ark-r1cs-std = { version = "^0.3.0", default-features = false}
ark-sponge = { version = "^0.3.0", default-features = false }
ark-poly = { version = "0.3.0", default-features = false }
tracing = { version = "0.1", default-features = false, features = [ "attributes" ], optional = true}


[dev-dependencies]
ark-test-curves = { version = "^0.3.0", default-features = false, features = ["bls12_381_scalar_field", "mnt4_753_scalar_field"] }

[features]
default = ["std"]
std = ["ark-ff/std", "ark-std/std", "ark-relations/std", "ark-r1cs-std/std", "ark-sponge/std", "ark-poly/std"]
r1cs = ["ark-sponge/r1cs", "tracing"]
35 changes: 35 additions & 0 deletions src/direct/constraints.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use ark_ff::PrimeField;
use ark_r1cs_std::boolean::Boolean;
use ark_r1cs_std::eq::EqGadget;
use ark_r1cs_std::fields::fp::FpVar;
use ark_r1cs_std::poly::polynomial::univariate::dense::DensePolynomialVar;
use ark_relations::r1cs::SynthesisError;
use ark_std::marker::PhantomData;

pub struct DirectLDTGadget<CF: PrimeField> {
_marker: PhantomData<CF>,
}

impl<CF: PrimeField> DirectLDTGadget<CF> {
/// ### Verifier Side
///
/// Verifier sample one element from domain and get its evaluation. Check if that evaluation
/// agrees with low-degree polynomial. Assume that `DensePolynomial` is low-degree, and verifier
/// need to check that.
tsunrise marked this conversation as resolved.
Show resolved Hide resolved
pub fn verify_low_degree_single_round(
tsunrise marked this conversation as resolved.
Show resolved Hide resolved
sampled_domain_element: FpVar<CF>,
sampled_evaluation_element: FpVar<CF>,
coefficients: &DensePolynomialVar<CF>,
degree_bound: usize,
) -> Result<Boolean<CF>, SynthesisError> {
// make sure the degree is within degree_bound. No need to include degree_bound check
// in constraints because the verifier can just verify the size of circuit.
assert!(
coefficients.coeffs.len() <= degree_bound + 1,
"polynomial degree out of bound"
);
coefficients
.evaluate(&sampled_domain_element)?
.is_eq(&sampled_evaluation_element)
}
}
133 changes: 133 additions & 0 deletions src/direct/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/// R1CS constraints for DirectLDT
#[cfg(feature = "r1cs")]
pub mod constraints;

use crate::domain::Radix2CosetDomain;
use ark_ff::PrimeField;
use ark_poly::univariate::DensePolynomial;
use ark_poly::Polynomial;
use ark_std::marker::PhantomData;
use ark_std::vec::Vec;
/// Direct LDT by interpolating evaluations and truncating coefficients to low degree.
pub struct DirectLDT<F: PrimeField> {
marker: PhantomData<F>,
}

/// A linear-communication protocol for testing if a function is a polynomial of certain degree.
/// Method is described in Aurora appendix C.1.
///
/// For now, the domain of the function needs to support IFFT.
impl<F: PrimeField> DirectLDT<F> {
/// ### Prover Side
///
/// Generate the coefficient of the low-degree polynomial obtained by interpolating the domain evaluations.
/// The polynomial is trimmed to `degree_bound` as necessary.
pub fn generate_low_degree_coefficients(
domain: Radix2CosetDomain<F>,
evaluations: Vec<F>,
degree_bound: usize,
) -> DensePolynomial<F> {
let mut poly = domain.interpolate(evaluations);
// trim higher degree: if poly is higher degree, then the soundness should fail
poly.coeffs.truncate(degree_bound + 1);
poly
}

/// ### Verifier Side
///
/// Verifier sample one element from domain and get its evaluation. Check if that evaluation
/// agrees with low-degree polynomial.
pub fn verify_low_degree_single_round(
sampled_domain_element: F,
sampled_evaluation_element: F,
coefficients: &DensePolynomial<F>,
) -> bool {
return coefficients.evaluate(&sampled_domain_element) == sampled_evaluation_element;
}
}

#[cfg(test)]
mod tests {
use crate::direct::{DirectLDT, Radix2CosetDomain};
use ark_ff::UniformRand;
use ark_poly::univariate::DensePolynomial;
use ark_poly::{EvaluationDomain, Polynomial, Radix2EvaluationDomain, UVPolynomial};
use ark_r1cs_std::alloc::AllocVar;
use ark_r1cs_std::fields::fp::FpVar;
use ark_r1cs_std::fields::FieldVar;
use ark_r1cs_std::poly::evaluations::univariate::EvaluationsVar;
use ark_r1cs_std::R1CSVar;
use ark_relations::r1cs::ConstraintSystem;
use ark_std::test_rng;
use ark_test_curves::bls12_381::Fr;

#[test]
fn test_native_coset() {
tsunrise marked this conversation as resolved.
Show resolved Hide resolved
let mut rng = test_rng();
let degree = 51;
let poly = DensePolynomial::<Fr>::rand(degree, &mut rng);
let base_domain = Radix2EvaluationDomain::new(degree + 1).unwrap();
let offset = Fr::rand(&mut rng);
let coset = Radix2CosetDomain::new(base_domain, offset);

// test evaluation
let expected_eval: Vec<_> = coset
.base_domain
.elements()
.map(|x| poly.evaluate(&(offset * x)))
.collect();
let actual_eval = coset.evaluate(&poly);
assert_eq!(actual_eval, expected_eval);

// test interpolation
let interpolated_poly = coset.interpolate(expected_eval.to_vec());
assert_eq!(interpolated_poly, poly);

// test consistency with r1cs-std
let cs = ConstraintSystem::new_ref();
let eval_var: Vec<_> = expected_eval
.iter()
.map(|x| FpVar::new_witness(ark_relations::ns!(cs, "eval_var"), || Ok(*x)).unwrap())
.collect();
let r1cs_coset = ark_r1cs_std::poly::domain::Radix2DomainVar {
gen: base_domain.group_gen,
offset: FpVar::constant(offset),
dim: ark_std::log2(degree.next_power_of_two()) as u64,
};
let eval_var = EvaluationsVar::from_vec_and_domain(eval_var, r1cs_coset, true);

let pt = Fr::rand(&mut rng);
let pt_var = FpVar::new_witness(ark_relations::ns!(cs, "random point"), || Ok(pt)).unwrap();

let expected = poly.evaluate(&pt);
let actual = eval_var.interpolate_and_evaluate(&pt_var).unwrap();

assert_eq!(actual.value().unwrap(), expected);
assert!(cs.is_satisfied().unwrap());
}

#[test]
fn test_direct_ldt() {
let degree = 51;

let mut rng = test_rng();
let poly = DensePolynomial::<Fr>::rand(degree, &mut rng);
let domain_coset = Radix2CosetDomain::new_radix2_coset(52, Fr::rand(&mut rng));
let evaluations = domain_coset.evaluate(&poly);

let low_degree_poly = DirectLDT::generate_low_degree_coefficients(
domain_coset.clone(),
evaluations.to_vec(),
degree,
);

let sampled_element = domain_coset.element(15);
let sampled_evaluation = evaluations[15];

assert!(DirectLDT::verify_low_degree_single_round(
sampled_element,
sampled_evaluation,
&low_degree_poly
))
}
}
Loading