mirror of
https://github.com/arnaucube/ark-r1cs-std.git
synced 2026-01-08 15:01:29 +01:00
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>
This commit is contained in:
@@ -3,15 +3,16 @@
|
||||
### Breaking changes
|
||||
- #12 Make the output of the `ToBitsGadget` impl for `FpVar` fixed-size
|
||||
- #48 Add `Clone` trait bound to `CondSelectGadget`.
|
||||
### Features
|
||||
|
||||
### Features
|
||||
- #21 Add `UInt128`
|
||||
- #50 Add `DensePolynomialVar`
|
||||
|
||||
### Improvements
|
||||
- #5 Speedup BLS-12 pairing
|
||||
- #13 Add `ToConstraintFieldGadget` to `ProjectiveVar`
|
||||
- #15, #16 Allow `cs` to be `None` when converting a Montgomery point into a Twisted Edwards point
|
||||
- #20 Add `CondSelectGadget` impl for `UInt`s
|
||||
- #21 Add `UInt128`
|
||||
- #22 Reduce density of `three_bit_cond_neg_lookup`
|
||||
- #23 Reduce allocations in `UInt`s
|
||||
- #33 Speedup scalar multiplication by a constant
|
||||
|
||||
@@ -31,6 +31,7 @@ num-traits = {version = "0.2", default-features = false }
|
||||
|
||||
[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-poly = { git = "https://github.com/arkworks-rs/algebra", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -49,6 +49,8 @@ pub mod pairing;
|
||||
pub mod alloc;
|
||||
/// This module describes a trait for checking equality of variables.
|
||||
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
|
||||
/// list of variables.
|
||||
pub mod select;
|
||||
|
||||
2
src/poly/mod.rs
Normal file
2
src/poly/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
/// Modules for working with polynomials in coefficient forms.
|
||||
pub mod polynomial;
|
||||
2
src/poly/polynomial/mod.rs
Normal file
2
src/poly/polynomial/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
/// Module defining data structures for univariate polynomials.
|
||||
pub mod univariate;
|
||||
78
src/poly/polynomial/univariate/dense.rs
Normal file
78
src/poly/polynomial/univariate/dense.rs
Normal file
@@ -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
src/poly/polynomial/univariate/mod.rs
Normal file
2
src/poly/polynomial/univariate/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
||||
/// A dense univariate polynomial represented in coefficient form.
|
||||
pub mod dense;
|
||||
Reference in New Issue
Block a user