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 generic FFT implementation over curve scalars #155

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,14 @@ paste = "1.0.2"
proptest = "0.10"
proptest-derive = "0.2"
blake2 = "0.9"
criterion = "0.3"

[features]
default = ["rust-gmp-kzen"]

[package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "katex-header.html", "--cfg", "docsrs" ]

[[bench]]
name = "ffts_bench"
harness = false
66 changes: 66 additions & 0 deletions benches/ffts_bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use criterion::Throughput;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use curv::cryptographic_primitives::secret_sharing::{ffts::multiply_polynomials, Polynomial};
use curv::elliptic::curves::{Scalar, Secp256k1};
use std::time::Instant;

fn criterion_benchmark(c: &mut Criterion) {
let fft_sizes = vec![
2,
4,
8,
16,
32,
32 * 3,
149,
149 * 2,
149 * 4,
149 * 8,
149 * 16,
149 * 32,
149 * 2 * 3,
149 * 4 * 3,
149 * 8 * 3,
149 * 16 * 3,
32 * 3 * 149,
// 32 * 3 * 149 * 631,
];
let mut group = c.benchmark_group("multiply_polynomials");
for size in fft_sizes {
group.throughput(Throughput::Elements(size as u64));
group.sample_size(10);
group.bench_with_input(
BenchmarkId::new("multiply_polynomials", size),
&size,
|bench, &size| {
bench.iter_custom(move |iters| {
let a_polys: Vec<Polynomial<Secp256k1>> = (0..iters)
.map(|_| {
Polynomial::from_coefficients(
(0..size).map(|_| Scalar::random()).collect(),
)
})
.collect();
let b_polys: Vec<Polynomial<Secp256k1>> = (0..iters)
.map(|_| {
Polynomial::from_coefficients(
(0..size).map(|_| Scalar::random()).collect(),
)
})
.collect();
let start = Instant::now();
a_polys
.into_iter()
.zip(b_polys.into_iter())
.for_each(|(a, b)| {
multiply_polynomials(a, b);
});
start.elapsed()
});
},
);
}
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct LdeiStatement<E: Curve> {
pub alpha: Vec<Scalar<E>>,
pub g: Vec<Point<E>>,
pub x: Vec<Point<E>>,
pub d: u16,
pub d: usize,
}

impl<E: Curve> LdeiStatement<E> {
Expand All @@ -35,7 +35,7 @@ impl<E: Curve> LdeiStatement<E> {
witness: &LdeiWitness<E>,
alpha: Vec<Scalar<E>>,
g: Vec<Point<E>>,
d: u16,
d: usize,
) -> Result<Self, InvalidLdeiStatement> {
if g.len() != alpha.len() {
return Err(InvalidLdeiStatement::AlphaLengthDoesntMatchG);
Expand Down
36 changes: 18 additions & 18 deletions src/cryptographic_primitives/secret_sharing/feldman_vss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
License MIT: <https://github.com/KZen-networks/curv/blob/master/LICENSE>
*/

use std::convert::{TryFrom, TryInto};
use std::convert::TryFrom;
use std::{fmt, ops};

use serde::{Deserialize, Serialize};
Expand All @@ -17,8 +17,8 @@ use crate::ErrorSS::{self, VerifyShareError};

#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct ShamirSecretSharing {
pub threshold: u16, //t
pub share_count: u16, //n
pub threshold: usize, //t
pub share_count: usize, //n
}

/// Feldman VSS, based on Paul Feldman. 1987. A practical scheme for non-interactive verifiable secret sharing.
Expand Down Expand Up @@ -49,12 +49,12 @@ pub struct SecretShares<E: Curve> {
}

impl<E: Curve> VerifiableSS<E> {
pub fn reconstruct_limit(&self) -> u16 {
pub fn reconstruct_limit(&self) -> usize {
self.parameters.threshold + 1
}

// generate VerifiableSS from a secret
pub fn share(t: u16, n: u16, secret: &Scalar<E>) -> (VerifiableSS<E>, SecretShares<E>) {
pub fn share(t: usize, n: usize, secret: &Scalar<E>) -> (VerifiableSS<E>, SecretShares<E>) {
assert!(t < n);
let polynomial = Polynomial::<E>::sample_exact_with_fixed_const_term(t, secret.clone());
let shares = polynomial.evaluate_many_bigint(1..=n).collect();
Expand Down Expand Up @@ -104,12 +104,12 @@ impl<E: Curve> VerifiableSS<E> {

// generate VerifiableSS from a secret and user defined x values (in case user wants to distribute point f(1), f(4), f(6) and not f(1),f(2),f(3))
pub fn share_at_indices(
t: u16,
n: u16,
t: usize,
n: usize,
secret: &Scalar<E>,
index_vec: &[u16],
index_vec: &[usize],
) -> (VerifiableSS<E>, SecretShares<E>) {
assert_eq!(usize::from(n), index_vec.len());
assert_eq!(n, index_vec.len());

let polynomial = Polynomial::<E>::sample_exact_with_fixed_const_term(t, secret.clone());
let shares = polynomial
Expand Down Expand Up @@ -137,7 +137,7 @@ impl<E: Curve> VerifiableSS<E> {
// returns vector of coefficients
#[deprecated(since = "0.8.0", note = "please use Polynomial::sample instead")]
pub fn sample_polynomial(t: usize, coef0: &Scalar<E>) -> Vec<Scalar<E>> {
Polynomial::<E>::sample_exact_with_fixed_const_term(t.try_into().unwrap(), coef0.clone())
Polynomial::<E>::sample_exact_with_fixed_const_term(t, coef0.clone())
.coefficients()
.to_vec()
}
Expand All @@ -157,9 +157,9 @@ impl<E: Curve> VerifiableSS<E> {
Polynomial::<E>::from_coefficients(coefficients.to_vec()).evaluate(&point)
}

pub fn reconstruct(&self, indices: &[u16], shares: &[Scalar<E>]) -> Scalar<E> {
pub fn reconstruct(&self, indices: &[usize], shares: &[Scalar<E>]) -> Scalar<E> {
assert_eq!(shares.len(), indices.len());
assert!(shares.len() >= usize::from(self.reconstruct_limit()));
assert!(shares.len() >= self.reconstruct_limit());
// add one to indices to get points
let points = indices
.iter()
Expand Down Expand Up @@ -216,13 +216,13 @@ impl<E: Curve> VerifiableSS<E> {
tail.fold(head.clone(), |acc, x| acc + x)
}

pub fn validate_share(&self, secret_share: &Scalar<E>, index: u16) -> Result<(), ErrorSS> {
pub fn validate_share(&self, secret_share: &Scalar<E>, index: usize) -> Result<(), ErrorSS> {
let g = Point::generator();
let ss_point = g * secret_share;
self.validate_share_public(&ss_point, index)
}

pub fn validate_share_public(&self, ss_point: &Point<E>, index: u16) -> Result<(), ErrorSS> {
pub fn validate_share_public(&self, ss_point: &Point<E>, index: usize) -> Result<(), ErrorSS> {
let comm_to_point = self.get_point_commitment(index);
if *ss_point == comm_to_point {
Ok(())
Expand All @@ -231,7 +231,7 @@ impl<E: Curve> VerifiableSS<E> {
}
}

pub fn get_point_commitment(&self, index: u16) -> Point<E> {
pub fn get_point_commitment(&self, index: usize) -> Point<E> {
let index_fe = Scalar::from(index);
let mut comm_iterator = self.commitments.iter().rev();
let head = comm_iterator.next().unwrap();
Expand All @@ -243,10 +243,10 @@ impl<E: Curve> VerifiableSS<E> {
// used in http://stevengoldfeder.com/papers/GG18.pdf
pub fn map_share_to_new_params(
_params: &ShamirSecretSharing,
index: u16,
s: &[u16],
index: usize,
s: &[usize],
) -> Scalar<E> {
let j = (0u16..)
let j = (0usize..)
.zip(s)
.find_map(|(j, s_j)| if *s_j == index { Some(j) } else { None })
.expect("`s` doesn't include `index`");
Expand Down
Loading