Skip to content

Commit c656804

Browse files
committed
Operations, comments and tests
1 parent d207fc7 commit c656804

File tree

9 files changed

+207
-12
lines changed

9 files changed

+207
-12
lines changed

src/math/ec/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ pub mod secp256k1;
88
pub trait EllipticCurve<const LIMBS: usize>:
99
Serialize + for<'a> Deserialize<'a> + PartialEq + Copy + Clone
1010
{
11+
/// Field of coefficients of the elliptic curve.
1112
type ScalarField: FiniteField<LIMBS>;
1213

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

18+
/// The zero point in the elliptic courve group.
1719
const ZERO: Self;
1820

1921
/// Returns the generator of the curve.

src/math/ec/secp256k1.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,17 @@ pub struct Secp256k1(
2323
pub struct AffinePoint(Secp256k1PrimeField, Secp256k1PrimeField);
2424

2525
impl AffinePoint {
26+
/// Returns the x-coordinate of the affine point.
2627
pub fn x(&self) -> &Secp256k1PrimeField {
2728
&self.0
2829
}
2930

31+
/// Returns the y-coordinate of the affine point.
3032
pub fn y(&self) -> &Secp256k1PrimeField {
3133
&self.1
3234
}
3335

36+
/// Checks if the affine point lies in the elliptic curve.
3437
pub fn is_valid(&self) -> bool {
3538
let b = Secp256k1PrimeField::from(7);
3639
let lhs = self.y().mul(self.y());
@@ -78,6 +81,7 @@ impl Secp256k1 {
7881
self.z().eq(&Secp256k1PrimeField::ZERO)
7982
}
8083

84+
/// Doubles this point.
8185
pub fn dbl(&self) -> Self {
8286
let b3 = Secp256k1PrimeField::from(3 * 7);
8387

src/math/field/secp256k1_prime.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ use crypto_bigint::{rand_core::RngCore, NonZero, RandomMod, Uint, Zero};
44
use serde::{Deserialize, Serialize};
55
use std::ops::{Add, Div, Mul, Sub};
66

7+
/// Represents an element in the field in which secp256k1 is defined.
78
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
89
pub struct Secp256k1PrimeField(Uint<4>);
910

1011
impl Secp256k1PrimeField {
12+
/// Created a new point in the field in which secp256k1 is defined.
1113
pub fn new(value: Uint<4>) -> Self {
1214
Self(value)
1315
}

src/math/field/secp256k1_scalar.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ use std::ops::{Add, Div, Mul, Sub};
66

77
const LIMBS: usize = 4;
88

9+
/// Represents a finite field modulo a secp256k1 prime order sub-group.
910
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
1011
pub struct Secp256k1ScalarField(Uint<LIMBS>);
1112

1213
impl Secp256k1ScalarField {
14+
/// Computes the NAF representation of this field element.
1315
pub fn to_naf(&self) -> NafEncoding {
1416
let mut naf = NafEncoding::new(Self::BIT_SIZE + 1);
1517
let mut val = self.0;
@@ -115,6 +117,7 @@ impl Div<&Self> for Secp256k1ScalarField {
115117
}
116118
}
117119

120+
/// Returns `true` if the bit in the position is 1, otherwise returns `false`.
118121
fn test_bit<const LIMBS: usize>(input: Uint<LIMBS>, pos: usize) -> bool {
119122
assert!((pos as u32) < LIMBS as u32 * Limb::BITS);
120123
let bits_per_limb = Limb::BITS;

src/math/poly.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
4040
result
4141
}
4242

43+
/// Returns the coefficients of the polynomial.
4344
pub fn coefficients(&self) -> &[T] {
4445
&self.0
4546
}
4647

48+
/// Returns the degree of the polynomial.
4749
pub fn degree(&self) -> usize {
4850
self.0.len() - 1
4951
}
@@ -57,12 +59,18 @@ impl<const LIMBS: usize, T: FiniteField<LIMBS>> Polynomial<LIMBS, T> {
5759
Self(coefficients)
5860
}
5961

62+
/// Changes the value of the constant coefficient of the polynomial.
6063
pub fn set_constant_coeff(&mut self, value: T) {
6164
self[0] = value;
6265
}
6366

67+
/// Creates a polynomial from its coefficients.
68+
///
69+
/// # Errors
70+
///
71+
/// If the array of coefficients is empty, the function returns [`Error::EmptyCoefficients`].
6472
pub fn new(coef: Vec<T>) -> Result<Self, T> {
65-
if coef.len() == 0 {
73+
if coef.is_empty() {
6674
Err(Error::EmptyCoefficients)
6775
} else {
6876
Ok(Self(coef))
@@ -92,7 +100,12 @@ impl<const LIMBS: usize, const N: usize, T: FiniteField<LIMBS>> From<[T; N]>
92100
}
93101
}
94102

95-
/// Computes the lagrange basis evaluated at `x`
103+
/// Computes the lagrange basis evaluated at `x`.
104+
///
105+
/// # Errors
106+
///
107+
/// The function returns [`Error::NotAllDifferentInterpolation`] if the list of nodes are not all
108+
/// different.
96109
pub fn compute_lagrange_basis<const LIMBS: usize, T: FiniteField<LIMBS>>(
97110
nodes: &[T],
98111
x: &T,
@@ -135,6 +148,10 @@ fn all_different<T: Ring>(list: &[T]) -> bool {
135148
}
136149

137150
/// Computes the evaluation of the interpolated polynomial at `x`.
151+
///
152+
/// # Error
153+
///
154+
/// If the lagrange basis is not computed correctly, the function returns an [`Error`].
138155
pub fn interpolate_polynomial_at<const LIMBS: usize, T: FiniteField<LIMBS>>(
139156
evaluations: &[T],
140157
alphas: &[T],

src/math/ring.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@ pub trait Ring:
2121
+ Copy
2222
+ Hash
2323
{
24+
/// Bit size of an element of the ring.
2425
const BIT_SIZE: usize;
26+
2527
/// Additive identity of the ring.
2628
const ZERO: Self;
2729

30+
/// Number of limbs used to represent a ring element.
2831
const LIMBS: usize;
2932

3033
/// Multiplicative identity of the ring.
@@ -36,5 +39,6 @@ pub trait Ring:
3639
/// Generates a random finite ring element with a provided pseudo-random generator.
3740
fn random<R: RngCore>(generator: &mut R) -> Self;
3841

42+
/// Returns a non-zero element from the ring sampled uniformly at random.
3943
fn random_non_zero<R: RngCore>(generator: &mut R) -> Self;
4044
}

src/math/vector.rs

Lines changed: 85 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@ use crypto_bigint::rand_core::RngCore;
33
use serde::Serialize;
44
use std::ops::{Add, Index, IndexMut, Mul, Sub};
55

6+
#[derive(thiserror::Error, Debug)]
7+
pub enum Error {
8+
#[error("the operands do not have the same dimension: {0:?} and {1:?}")]
9+
IncompatibleDimension(usize, usize),
10+
}
11+
12+
pub type Result<T> = std::result::Result<T, Error>;
13+
614
/// Vector whose elements belong to a ring.
7-
#[derive(Serialize, PartialEq, Eq, Debug)]
15+
#[derive(Serialize, PartialEq, Eq, Debug, Clone)]
816
pub struct Vector<T: Ring>(Vec<T>);
917

1018
impl<T> Vector<T>
@@ -16,8 +24,9 @@ where
1624
self.0.len()
1725
}
1826

27+
/// Returns whether the vector has no elements.
1928
pub fn is_empty(&self) -> bool {
20-
self.len() == 0
29+
self.0.is_empty()
2130
}
2231

2332
/// Generates a vector of zeroes.
@@ -40,12 +49,15 @@ where
4049
}
4150

4251
/// Computes the dot product between two vectors.
43-
pub fn dot(&self, other: &Vector<T>) -> T {
52+
pub fn dot(&self, other: &Vector<T>) -> Result<T> {
53+
if self.len() != other.len() {
54+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
55+
}
4456
let mut result = T::ZERO;
4557
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
4658
result = result + &(*self_elem * other_elem);
4759
}
48-
result
60+
Ok(result)
4961
}
5062
}
5163

@@ -82,43 +94,106 @@ impl<T> Add<&Vector<T>> for Vector<T>
8294
where
8395
T: Ring,
8496
{
85-
type Output = Self;
97+
type Output = Result<Self>;
8698

8799
fn add(self, other: &Vector<T>) -> Self::Output {
100+
if self.len() != other.len() {
101+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
102+
}
88103
let mut output = Vec::with_capacity(other.0.len());
89104
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
90105
output.push(*self_elem + other_elem);
91106
}
92-
Self(output)
107+
Ok(Self(output))
108+
}
109+
}
110+
111+
impl<T> Add<&Vector<T>> for &Vector<T>
112+
where
113+
T: Ring,
114+
{
115+
type Output = Result<Vector<T>>;
116+
117+
fn add(self, other: &Vector<T>) -> Self::Output {
118+
if self.len() != other.len() {
119+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
120+
}
121+
let mut output = Vec::with_capacity(other.0.len());
122+
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
123+
output.push(*self_elem + other_elem);
124+
}
125+
Ok(Vector(output))
93126
}
94127
}
95128

96129
impl<T> Sub<&Vector<T>> for Vector<T>
97130
where
98131
T: Ring,
99132
{
100-
type Output = Self;
133+
type Output = Result<Self>;
134+
135+
fn sub(self, other: &Vector<T>) -> Self::Output {
136+
if self.len() != other.len() {
137+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
138+
}
139+
let mut output = Vec::with_capacity(other.0.len());
140+
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
141+
output.push(*self_elem - other_elem);
142+
}
143+
Ok(Self(output))
144+
}
145+
}
146+
147+
impl<T> Sub<&Vector<T>> for &Vector<T>
148+
where
149+
T: Ring,
150+
{
151+
type Output = Result<Vector<T>>;
101152

102153
fn sub(self, other: &Vector<T>) -> Self::Output {
154+
if self.len() != other.len() {
155+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
156+
}
103157
let mut output = Vec::with_capacity(other.0.len());
104158
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
105159
output.push(*self_elem - other_elem);
106160
}
107-
Self(output)
161+
Ok(Vector(output))
108162
}
109163
}
110164

111165
impl<T> Mul<&Vector<T>> for Vector<T>
112166
where
113167
T: Ring,
114168
{
115-
type Output = Self;
169+
type Output = Result<Self>;
116170

117171
fn mul(self, other: &Vector<T>) -> Self::Output {
172+
if self.len() != other.len() {
173+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
174+
}
175+
let mut output = Vec::with_capacity(other.0.len());
176+
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
177+
output.push(*self_elem * other_elem);
178+
}
179+
Ok(Self(output))
180+
}
181+
}
182+
183+
impl<T> Mul<&Vector<T>> for &Vector<T>
184+
where
185+
T: Ring,
186+
{
187+
type Output = Result<Vector<T>>;
188+
189+
fn mul(self, other: &Vector<T>) -> Self::Output {
190+
if self.len() != other.len() {
191+
return Err(Error::IncompatibleDimension(self.len(), other.len()));
192+
}
118193
let mut output = Vec::with_capacity(other.0.len());
119194
for (self_elem, other_elem) in self.0.iter().zip(other.0.iter()) {
120195
output.push(*self_elem * other_elem);
121196
}
122-
Self(output)
197+
Ok(Vector(output))
123198
}
124199
}

src/net/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,23 @@ use std::{
2121
};
2222
use thiserror::Error;
2323

24+
/// Error type for network errors.
2425
#[derive(Debug, Error)]
2526
pub enum NetworkError {
27+
/// Encapsulates a TLS error.
2628
#[error("TLS error: {0:?}")]
2729
TlsError(rustls::Error),
2830

31+
/// This error is returned when there is an IO error.
2932
#[error("IO error: {0:?}")]
3033
IoError(io::Error),
3134

35+
/// This error encapsulates a channel error.
3236
#[error("channel error: {0:?}")]
3337
ChannelError(channel::ChannelError),
3438
}
3539

40+
/// Special type for the network error.
3641
pub type Result<T> = std::result::Result<T, NetworkError>;
3742

3843
// This packet can be changed such that the elements in it can be of multiple types.
@@ -71,17 +76,20 @@ impl Packet {
7176
self.0.len()
7277
}
7378

79+
/// Extract the first element in the packet.
7480
pub fn pop<'de, T>(&mut self) -> T
7581
where
7682
T: Deserialize<'de>,
7783
{
7884
todo!()
7985
}
8086

87+
/// Read the element at the given index inside the packet.
8188
pub fn read<T>(&self, _obj_idx: usize) -> T {
8289
todo!()
8390
}
8491

92+
/// Write an element at the end of the packet.
8593
pub fn write<T>(&mut self, _obj: T)
8694
where
8795
T: Serialize,
@@ -206,6 +214,12 @@ pub struct Network {
206214
}
207215

208216
impl Network {
217+
/// Configure the TLS channel according to the provided network configuration.
218+
///
219+
/// # Error
220+
///
221+
/// The function returns an error if the cerificate and the private key are not configured
222+
/// correctly.
209223
fn configure_tls(config: &NetworkConfig<'static>) -> Result<(ClientConfig, ServerConfig)> {
210224
// Configure the client TLS
211225
let client_conf = ClientConfig::builder()
@@ -222,6 +236,15 @@ impl Network {
222236

223237
/// Creates a new network using the ID of the current party and the number of parties connected
224238
/// to the network.
239+
///
240+
/// # Error
241+
///
242+
/// The function returns an error in the following cases:
243+
/// - When the binding of the channel to a certain IP address is
244+
/// not done correctly.
245+
/// - When the TLS configuration is not done correctly.
246+
/// - When the node is trying to connect as a server but is unable to accept the provided
247+
/// client.
225248
pub fn create(id: usize, config: NetworkConfig<'static>) -> Result<Self> {
226249
log::info!("creating network");
227250
let n_parties = config.peer_ips.len();

0 commit comments

Comments
 (0)