Skip to content

Commit

Permalink
Add polynomial (de)serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
survived committed Jun 27, 2023
1 parent 6ff5216 commit 50ce9fa
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 33 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
Cargo.lock

/.idea

.helix/
63 changes: 30 additions & 33 deletions generic-ec-zkp/src/polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use core::{iter, ops};

use generic_ec::{
traits::{Samplable, Zero},
traits::{IsZero, Samplable, Zero},
Curve, NonZero, Scalar,
};
use rand_core::RngCore;
Expand All @@ -20,7 +20,7 @@ pub struct Polynomial<C> {
coefs: Vec<C>,
}

impl<C: Zero> Polynomial<C> {
impl<C: IsZero> Polynomial<C> {
/// Constructs a polynomial from its coefficients
///
/// `coefs[i]` is coefficient of `x^i` term. Resulting polynomial will be
Expand Down Expand Up @@ -50,7 +50,7 @@ impl<C: Zero> Polynomial<C> {
let zeroes_count = coefs
.iter()
.rev()
.take_while(|coef_i| Zero::is_zero(*coef_i).into())
.take_while(|coef_i| coef_i.is_zero())
.count();
let coefs_len = coefs.len();
coefs.truncate(coefs_len - zeroes_count);
Expand All @@ -59,36 +59,6 @@ impl<C: Zero> Polynomial<C> {
}
}

impl<C> Polynomial<NonZero<C>> {
/// Constructs a polynomial from its non-zero coefficients
///
/// Similar to [`Polynomial::from_coefs`], but it doesn't require coefficients to
/// implement [`Zero`] trait, instead it requires coefficients to be non-zero.
///
/// ## Example
/// ```rust
/// # use rand_core::OsRng;
/// use generic_ec::{Scalar, NonZero, curves::Secp256k1};
/// use generic_ec_zkp::polynomial::Polynomial;
///
/// let coefs: [NonZero<Scalar<Secp256k1>>; 3] = [
/// NonZero::random(&mut OsRng),
/// NonZero::random(&mut OsRng),
/// NonZero::random(&mut OsRng),
/// ];
/// let polynomial = Polynomial::from_nonzero_coefs(coefs.to_vec());
///
/// let x = Scalar::random(&mut OsRng);
/// assert_eq!(
/// coefs[0] + x * coefs[1] + x * x * coefs[2],
/// polynomial.value(&x),
/// );
/// ```
pub fn from_nonzero_coefs(coefs: Vec<NonZero<C>>) -> Self {
Self { coefs }
}
}

impl<C> Polynomial<C> {
/// Returns polynomial degree
///
Expand Down Expand Up @@ -278,6 +248,33 @@ where
}
}

#[cfg(feature = "serde")]
impl<C> serde::Serialize for Polynomial<C>
where
C: serde::Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.coefs.serialize(serializer)
}
}

#[cfg(feature = "serde")]
impl<'de, C: IsZero> serde::Deserialize<'de> for Polynomial<C>
where
C: serde::Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let coefs = Vec::<C>::deserialize(deserializer)?;
Ok(Self::from_coefs(coefs))
}
}

/// Calculates lagrange coefficient $\lambda_j$ to interpolate a polynomial at point $x$
///
/// Lagrange coefficient are often used to turn polynomial key shares into additive
Expand Down
6 changes: 6 additions & 0 deletions generic-ec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ mod secret_scalar;
pub mod traits {
#[doc(inline)]
pub use crate::core::{One, Samplable, Zero};

/// Trait that allows you to check whether value is zero
pub trait IsZero {
/// Checks whether `self` is zero
fn is_zero(&self) -> bool;
}
}

#[cfg(feature = "serde")]
Expand Down
8 changes: 8 additions & 0 deletions generic-ec/src/non_zero/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ impl<E: Curve> crate::traits::Samplable for NonZero<Scalar<E>> {
}
}

impl<T> crate::traits::IsZero for NonZero<T> {
/// Returns `false` as `NonZero<T>` cannot be zero
#[inline(always)]
fn is_zero(&self) -> bool {
false
}
}

impl<E: Curve> crate::traits::One for NonZero<Scalar<E>> {
fn one() -> Self {
Self::one()
Expand Down
6 changes: 6 additions & 0 deletions generic-ec/src/point/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ impl<E: Curve> Ord for Point<E> {
}
}

impl<E: Curve> crate::traits::IsZero for Point<E> {
fn is_zero(&self) -> bool {
*self == Point::zero()
}
}

impl<E: Curve> crate::traits::Zero for Point<E> {
fn zero() -> Self {
Point::zero()
Expand Down
6 changes: 6 additions & 0 deletions generic-ec/src/scalar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ impl<E: Curve> AsRef<Scalar<E>> for Scalar<E> {
}
}

impl<E: Curve> crate::traits::IsZero for Scalar<E> {
fn is_zero(&self) -> bool {
*self == Scalar::zero()
}
}

impl<E: Curve> crate::traits::Zero for Scalar<E> {
fn zero() -> Self {
Scalar::zero()
Expand Down

0 comments on commit 50ce9fa

Please sign in to comment.