Browse Source

Add DensePolynomialVar (#50)

* add folder structures similar to `ark-poly`

* add evaluate impl for DensePolynomialVar

* add tests

* fix no-std

* use ark_std::rand instead of SeedableRng

* add changelog

Co-authored-by: Weikeng Chen <w.k@berkeley.edu>
master
Tom Shen 3 years ago
committed by GitHub
parent
commit
09f3613aac
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 2 deletions
  1. +3
    -2
      CHANGELOG.md
  2. +1
    -0
      Cargo.toml
  3. +2
    -0
      src/lib.rs
  4. +2
    -0
      src/poly/mod.rs
  5. +2
    -0
      src/poly/polynomial/mod.rs
  6. +78
    -0
      src/poly/polynomial/univariate/dense.rs
  7. +2
    -0
      src/poly/polynomial/univariate/mod.rs

+ 3
- 2
CHANGELOG.md

@ -3,15 +3,16 @@
### Breaking changes ### Breaking changes
- #12 Make the output of the `ToBitsGadget` impl for `FpVar` fixed-size - #12 Make the output of the `ToBitsGadget` impl for `FpVar` fixed-size
- #48 Add `Clone` trait bound to `CondSelectGadget`. - #48 Add `Clone` trait bound to `CondSelectGadget`.
### Features
### Features
- #21 Add `UInt128`
- #50 Add `DensePolynomialVar`
### Improvements ### Improvements
- #5 Speedup BLS-12 pairing - #5 Speedup BLS-12 pairing
- #13 Add `ToConstraintFieldGadget` to `ProjectiveVar` - #13 Add `ToConstraintFieldGadget` to `ProjectiveVar`
- #15, #16 Allow `cs` to be `None` when converting a Montgomery point into a Twisted Edwards point - #15, #16 Allow `cs` to be `None` when converting a Montgomery point into a Twisted Edwards point
- #20 Add `CondSelectGadget` impl for `UInt`s - #20 Add `CondSelectGadget` impl for `UInt`s
- #21 Add `UInt128`
- #22 Reduce density of `three_bit_cond_neg_lookup` - #22 Reduce density of `three_bit_cond_neg_lookup`
- #23 Reduce allocations in `UInt`s - #23 Reduce allocations in `UInt`s
- #33 Speedup scalar multiplication by a constant - #33 Speedup scalar multiplication by a constant

+ 1
- 0
Cargo.toml

@ -31,6 +31,7 @@ num-traits = {version = "0.2", default-features = false }
[dev-dependencies] [dev-dependencies]
ark-test-curves = { git = "https://github.com/arkworks-rs/algebra", default-features = false, features = ["bls12_381_scalar_field", "mnt4_753_scalar_field"] } ark-test-curves = { git = "https://github.com/arkworks-rs/algebra", default-features = false, features = ["bls12_381_scalar_field", "mnt4_753_scalar_field"] }
ark-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
[features] [features]
default = ["std"] default = ["std"]

+ 2
- 0
src/lib.rs

@ -49,6 +49,8 @@ pub mod pairing;
pub mod alloc; pub mod alloc;
/// This module describes a trait for checking equality of variables. /// This module describes a trait for checking equality of variables.
pub mod eq; pub mod eq;
/// This module implements functions for manipulating polynomial variables over finite fields.
pub mod poly;
/// This module describes traits for conditionally selecting a variable from a /// This module describes traits for conditionally selecting a variable from a
/// list of variables. /// list of variables.
pub mod select; pub mod select;

+ 2
- 0
src/poly/mod.rs

@ -0,0 +1,2 @@
/// Modules for working with polynomials in coefficient forms.
pub mod polynomial;

+ 2
- 0
src/poly/polynomial/mod.rs

@ -0,0 +1,2 @@
/// Module defining data structures for univariate polynomials.
pub mod univariate;

+ 78
- 0
src/poly/polynomial/univariate/dense.rs

@ -0,0 +1,78 @@
use ark_ff::PrimeField;
use ark_relations::r1cs::SynthesisError;
use crate::fields::fp::FpVar;
use crate::fields::FieldVar;
use ark_std::vec::Vec;
/// Stores a polynomial in coefficient form, where coeffcient is represented by a list of `Fpvar<F>`.
pub struct DensePolynomialVar<F: PrimeField> {
/// The coefficient of `x^i` is stored at location `i` in `self.coeffs`.
pub coeffs: Vec<FpVar<F>>,
}
impl<F: PrimeField> DensePolynomialVar<F> {
/// Constructs a new polynomial from a list of coefficients.
pub fn from_coefficients_slice(coeffs: &[FpVar<F>]) -> Self {
Self::from_coefficients_vec(coeffs.to_vec())
}
/// Constructs a new polynomial from a list of coefficients.
pub fn from_coefficients_vec(coeffs: Vec<FpVar<F>>) -> Self {
Self { coeffs }
}
/// Evaluates `self` at the given `point` and just gives you the gadget for the result.
/// Caution for use in holographic lincheck: The output has 2 entries in one matrix
pub fn evaluate(&self, point: &FpVar<F>) -> Result<FpVar<F>, SynthesisError> {
let mut result: FpVar<F> = FpVar::zero();
// current power of point
let mut curr_pow_x: FpVar<F> = FpVar::one();
for i in 0..self.coeffs.len() {
let term = &curr_pow_x * &self.coeffs[i];
result += &term;
curr_pow_x *= point;
}
Ok(result)
}
}
#[cfg(test)]
mod tests {
use crate::alloc::AllocVar;
use crate::fields::fp::FpVar;
use crate::poly::polynomial::univariate::dense::DensePolynomialVar;
use crate::R1CSVar;
use ark_poly::polynomial::univariate::DensePolynomial;
use ark_poly::{Polynomial, UVPolynomial};
use ark_relations::r1cs::ConstraintSystem;
use ark_std::vec::Vec;
use ark_std::{test_rng, UniformRand};
use ark_test_curves::bls12_381::Fr;
#[test]
fn test_evaluate() {
let mut rng = test_rng();
for _ in 0..100 {
let cs = ConstraintSystem::new_ref();
let poly: DensePolynomial<Fr> = DensePolynomial::rand(10, &mut rng);
let poly_var = {
let coeff: Vec<_> = poly
.coeffs
.iter()
.map(|&x| FpVar::new_witness(ns!(cs, "coeff"), || Ok(x)).unwrap())
.collect();
DensePolynomialVar::from_coefficients_vec(coeff)
};
let point = Fr::rand(&mut rng);
let point_var = FpVar::new_witness(ns!(cs, "point"), || Ok(point)).unwrap();
let expected = poly.evaluate(&point);
let actual = poly_var.evaluate(&point_var).unwrap();
assert_eq!(actual.value().unwrap(), expected);
assert!(cs.is_satisfied().unwrap());
}
}
}

+ 2
- 0
src/poly/polynomial/univariate/mod.rs

@ -0,0 +1,2 @@
/// A dense univariate polynomial represented in coefficient form.
pub mod dense;

Loading…
Cancel
Save