Skip to content

Commit d207fc7

Browse files
committed
Added some secret sharing schemes
1 parent 885ef03 commit d207fc7

File tree

18 files changed

+217
-97
lines changed

18 files changed

+217
-97
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ library. The interaction between parties are done using the functions `send` and
8181
## Missing features
8282

8383
- [x] ~Implement secp256k1~.
84-
- [ ] Implement Feldman VSS.
84+
- [x] ~Implement Feldman VSS~.
8585
- [ ] Document the source code.
86-
- [ ] Implement Shamir's secret-sharing.
86+
- [x] ~Implement Shamir's secret-sharing.~
8787
- [ ] Implement a fake network so that the final user can prototype MPC protocols locally.
8888
- [ ] Implement polynomials over the prime field of the elliptic curves which is useful for Feldman VSS.
8989
- [ ] Improve the serialization and deserialization to optimize the communication.

src/math/ec/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
use serde::{Deserialize, Serialize};
2-
31
use super::field::FiniteField;
2+
use serde::{Deserialize, Serialize};
43

54
pub mod secp256k1;
65

76
/// Trait that defines an elliptic curve point using certain number of limbs for the scalar and
87
/// prime field.
9-
pub trait EllipticCurve<const LIMBS: usize>: Serialize + for<'a> Deserialize<'a> {
8+
pub trait EllipticCurve<const LIMBS: usize>:
9+
Serialize + for<'a> Deserialize<'a> + PartialEq + Copy + Clone
10+
{
1011
type ScalarField: FiniteField<LIMBS>;
1112

1213
/// Field in which the elliptic curve is defined. The points in the elliptic curve will be
1314
/// pairs in this field.
1415
type PrimeField: FiniteField<LIMBS>;
1516

17+
const ZERO: Self;
18+
1619
/// Returns the generator of the curve.
1720
fn gen() -> Self;
1821

@@ -26,9 +29,6 @@ pub trait EllipticCurve<const LIMBS: usize>: Serialize + for<'a> Deserialize<'a>
2629
/// point in the elliptic curve.
2730
fn scalar_mul(&self, rhs: &Self::ScalarField) -> Self;
2831

29-
/// Returns whether two points in the elliptic curve are equal.
30-
fn eq(&self, other: &Self) -> bool;
31-
3232
/// Returns the additive inverse of the point in the elliptic curve.
3333
fn negate(&self) -> Self;
3434
}

src/math/ec/secp256k1.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
1-
use std::ops::{Add, Mul};
2-
3-
use crypto_bigint::Uint;
4-
use serde::{Deserialize, Serialize};
5-
61
use crate::math::{
72
field::{
83
secp256k1_prime::Secp256k1PrimeField, secp256k1_scalar::Secp256k1ScalarField, FiniteField,
94
},
105
ring::Ring,
116
};
7+
use crypto_bigint::Uint;
8+
use serde::{Deserialize, Serialize};
9+
use std::ops::{Add, Mul};
1210

1311
use super::EllipticCurve;
1412

1513
/// Implementation of secp256k1 using projective coordinates.
16-
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
14+
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq)]
1715
pub struct Secp256k1(
1816
Secp256k1PrimeField,
1917
Secp256k1PrimeField,
2018
Secp256k1PrimeField,
2119
);
2220

2321
/// Representation of a secp256k1 point using affine coordinates.
24-
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
22+
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
2523
pub struct AffinePoint(Secp256k1PrimeField, Secp256k1PrimeField);
2624

2725
impl AffinePoint {
@@ -114,6 +112,7 @@ impl Secp256k1 {
114112
impl EllipticCurve<4> for Secp256k1 {
115113
type ScalarField = Secp256k1ScalarField;
116114
type PrimeField = Secp256k1PrimeField;
115+
const ZERO: Self = Self::POINT_AT_INFINITY;
117116

118117
fn gen() -> Self {
119118
Self(
@@ -214,9 +213,15 @@ impl EllipticCurve<4> for Secp256k1 {
214213
fn sub(&self, rhs: &Self) -> Self {
215214
self.add(&rhs.negate())
216215
}
216+
}
217217

218+
impl PartialEq for Secp256k1 {
218219
fn eq(&self, other: &Self) -> bool {
219220
self.x().mul(other.z()).eq(&other.x().mul(self.z()))
220221
&& self.y().mul(other.z()).eq(&other.y().mul(self.z()))
221222
}
223+
224+
fn ne(&self, other: &Self) -> bool {
225+
!(self == other)
226+
}
222227
}

src/math/field/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use std::{fmt::Debug, ops::Div};
2-
31
use crate::math::ring;
42
use crypto_bigint::{NonZero, Uint};
3+
use std::{fmt::Debug, ops::Div};
54
use thiserror::Error;
65

76
/// This module contains an implementation of the field Mersenne 61 which is the
@@ -23,7 +22,9 @@ pub enum FieldError {
2322
}
2423

2524
/// Trait that represent a finite field of integers modulo a prime $p$.
26-
pub trait FiniteField<const LIMBS: usize>: ring::Ring + for<'a> Div<&'a Self> {
25+
pub trait FiniteField<const LIMBS: usize>:
26+
ring::Ring + for<'a> Div<&'a Self> + Copy + Clone
27+
{
2728
/// Modulus used in for the field represented in Little-Endian.
2829
const MODULUS: NonZero<Uint<LIMBS>>;
2930

src/math/field/secp256k1_prime.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
use std::ops::{Add, Div, Mul, Sub};
2-
1+
use super::{FieldError, FiniteField};
2+
use crate::math::ring::Ring;
33
use crypto_bigint::{rand_core::RngCore, NonZero, RandomMod, Uint, Zero};
44
use serde::{Deserialize, Serialize};
5+
use std::ops::{Add, Div, Mul, Sub};
56

6-
use crate::math::ring::Ring;
7-
8-
use super::{FieldError, FiniteField};
9-
10-
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Hash, Eq, Serialize, Deserialize)]
7+
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
118
pub struct Secp256k1PrimeField(Uint<4>);
129

1310
impl Secp256k1PrimeField {

src/math/field/secp256k1_scalar.rs

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,14 @@
1+
use super::{naf::NafEncoding, FieldError, FiniteField};
2+
use crate::math::ring::Ring;
13
use crypto_bigint::{rand_core::RngCore, Limb, NonZero, RandomMod, Uint, Zero};
2-
use std::ops::{Add, Div, Mul, Sub};
3-
44
use serde::{Deserialize, Serialize};
5-
6-
use crate::math::ring::Ring;
7-
8-
use super::{naf::NafEncoding, FieldError, FiniteField};
5+
use std::ops::{Add, Div, Mul, Sub};
96

107
const LIMBS: usize = 4;
118

129
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
1310
pub struct Secp256k1ScalarField(Uint<LIMBS>);
1411

15-
fn test_bit<const LIMBS: usize>(input: Uint<LIMBS>, pos: usize) -> bool {
16-
assert!((pos as u32) < LIMBS as u32 * Limb::BITS);
17-
let bits_per_limb = Limb::BITS;
18-
19-
let limbs_input = input.as_limbs();
20-
let limb = pos as u32 / bits_per_limb;
21-
let limb_pos = pos as u32 % bits_per_limb;
22-
((limbs_input[limb as usize] >> limb_pos) & Limb::ONE) == Limb::ONE
23-
}
24-
2512
impl Secp256k1ScalarField {
2613
pub fn to_naf(&self) -> NafEncoding {
2714
let mut naf = NafEncoding::new(Self::BIT_SIZE + 1);
@@ -48,7 +35,6 @@ impl Secp256k1ScalarField {
4835
}
4936

5037
impl FiniteField<4> for Secp256k1ScalarField {
51-
// TODO: Fix this number.
5238
const MODULUS: NonZero<Uint<4>> = NonZero::<Uint<4>>::new_unwrap(Uint::from_words([
5339
0xBFD25E8CD0364141,
5440
0xBAAEDCE6AF48A03B,
@@ -128,3 +114,13 @@ impl Div<&Self> for Secp256k1ScalarField {
128114
Ok(self.mul(&inverse))
129115
}
130116
}
117+
118+
fn test_bit<const LIMBS: usize>(input: Uint<LIMBS>, pos: usize) -> bool {
119+
assert!((pos as u32) < LIMBS as u32 * Limb::BITS);
120+
let bits_per_limb = Limb::BITS;
121+
122+
let limbs_input = input.as_limbs();
123+
let limb = pos as u32 / bits_per_limb;
124+
let limb_pos = pos as u32 % bits_per_limb;
125+
((limbs_input[limb as usize] >> limb_pos) & Limb::ONE) == Limb::ONE
126+
}

src/math/matrix.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
2-
1+
use super::{ring::Ring, vector::Vector};
32
use crypto_bigint::rand_core::RngCore;
3+
use serde::Serialize;
4+
use std::ops::{Add, AddAssign, Mul, Sub, SubAssign};
45
use thiserror::Error;
56

6-
use super::{ring::Ring, vector::Vector};
7-
87
/// Errors that may occurs when creating and operating with matrices.
98
#[derive(Error, Debug)]
109
pub enum Error {
@@ -21,6 +20,7 @@ pub enum Error {
2120
pub type Result<T> = std::result::Result<T, Error>;
2221

2322
/// Matrix with elements in a ring.
23+
#[derive(Serialize, Debug, Eq)]
2424
pub struct Matrix<T: Ring> {
2525
/// Elements of the matrix.
2626
elements: Vec<T>,

src/math/poly.rs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1+
use super::ring::Ring;
2+
use crate::math::field::FiniteField;
3+
use crypto_bigint::rand_core::RngCore;
4+
use serde::Serialize;
15
use std::{
26
collections::HashSet,
37
ops::{Index, IndexMut},
48
};
5-
6-
use crate::math::field::FiniteField;
7-
use crypto_bigint::rand_core::RngCore;
89
use thiserror::Error;
910

10-
use super::ring::Ring;
11-
1211
/// Errors for all the polynomial operations.
1312
#[derive(Debug, Error)]
1413
pub enum Error<T>
@@ -28,7 +27,7 @@ where
2827
pub type Result<T, R> = std::result::Result<T, Error<R>>;
2928

3029
/// Represents a polynomial whose coefficients are elements in a finite field.
31-
#[derive(PartialEq, Eq, Debug)]
30+
#[derive(PartialEq, Eq, Debug, Serialize)]
3231
pub struct Polynomial<const LIMBS: usize, T: FiniteField<LIMBS>>(Vec<T>);
3332

3433
impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
@@ -41,6 +40,14 @@ impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
4140
result
4241
}
4342

43+
pub fn coefficients(&self) -> &[T] {
44+
&self.0
45+
}
46+
47+
pub fn degree(&self) -> usize {
48+
self.0.len() - 1
49+
}
50+
4451
/// Generates a random polynomial of a given degree using a given pseudo-random generator.
4552
pub fn random<R: RngCore>(degree: usize, rng: &mut R) -> Self {
4653
let mut coefficients = Vec::with_capacity(degree + 1);
@@ -50,6 +57,10 @@ impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
5057
Self(coefficients)
5158
}
5259

60+
pub fn set_constant_coeff(&mut self, value: T) {
61+
self[0] = value;
62+
}
63+
5364
pub fn new(coef: Vec<T>) -> Result<Self, T> {
5465
if coef.len() == 0 {
5566
Err(Error::EmptyCoefficients)
@@ -82,12 +93,12 @@ impl<const LIMBS: usize, const N: usize, T: FiniteField<LIMBS>> From<[T; N]>
8293
}
8394

8495
/// Computes the lagrange basis evaluated at `x`
85-
pub(crate) fn compute_lagrange_basis<const LIMBS: usize, T: FiniteField<LIMBS>>(
86-
nodes: Vec<T>,
96+
pub fn compute_lagrange_basis<const LIMBS: usize, T: FiniteField<LIMBS>>(
97+
nodes: &[T],
8798
x: &T,
8899
) -> Result<Vec<T>, T> {
89-
if !all_different(&nodes) {
90-
return Err(Error::NotAllDifferentInterpolation(nodes));
100+
if !all_different(nodes) {
101+
return Err(Error::NotAllDifferentInterpolation(nodes.to_vec()));
91102
}
92103
let mut lagrange_basis = Vec::with_capacity(nodes.len());
93104
for j in 0..nodes.len() {
@@ -125,15 +136,15 @@ fn all_different<T: Ring>(list: &[T]) -> bool {
125136

126137
/// Computes the evaluation of the interpolated polynomial at `x`.
127138
pub fn interpolate_polynomial_at<const LIMBS: usize, T: FiniteField<LIMBS>>(
128-
evaluations: Vec<T>,
129-
alphas: Vec<T>,
139+
evaluations: &[T],
140+
alphas: &[T],
130141
x: &T,
131142
) -> Result<T, T> {
132143
assert!(alphas.len() > 0);
133144
assert!(alphas.len() == evaluations.len());
134145
let lagrange_basis = compute_lagrange_basis(alphas, x)?;
135146
let mut interpolation = T::ZERO;
136-
for (eval, basis) in evaluations.into_iter().zip(lagrange_basis) {
147+
for (eval, basis) in evaluations.iter().zip(lagrange_basis) {
137148
interpolation = interpolation.add(&eval.mul(&basis));
138149
}
139150
Ok(interpolation)

src/math/ring.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1+
use crypto_bigint::rand_core::RngCore;
2+
use serde::{Deserialize, Serialize};
13
use std::{
24
fmt::Debug,
35
hash::Hash,
46
ops::{Add, Mul, Sub},
57
};
68

7-
use crypto_bigint::rand_core::RngCore;
8-
use serde::{Deserialize, Serialize};
9-
109
/// This trait represent an algebraic finite Ring.
1110
pub trait Ring:
1211
Debug

src/math/vector.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use crypto_bigint::rand_core::RngCore;
2-
31
use super::ring::Ring;
2+
use crypto_bigint::rand_core::RngCore;
3+
use serde::Serialize;
44
use std::ops::{Add, Index, IndexMut, Mul, Sub};
55

66
/// Vector whose elements belong to a ring.
7+
#[derive(Serialize, PartialEq, Eq, Debug)]
78
pub struct Vector<T: Ring>(Vec<T>);
89

910
impl<T> Vector<T>

0 commit comments

Comments
 (0)