cf3fd00350
* - standardise versions for all nym-sdk workspace dependencies - prepend sqlx-pool-guard with 'nym-' * Test remove nym-api from deps * Add oneliner to client_pool doc comments * Add note to commented out docs.rs link in sdk * remove nym-api from script * add publishing file * bring non-binary / contract / tools into workspace version * added more info to publishing.md * make deps workspace version * remove uploaded sphinx-types crate from script * remove erroueously included ignore-defaults * add zeroise to feature * chore: Release * add topology to batch * more cargo versioning * more cargo versioning - wasm utils * more cargo versioning - wasm utils * Add publish=false to manifest for cargo workspaces / crates.io publishing exclusion * remove script now switched to manifest based exclusion * rename import based on rename of contracts-common dep * Making workspace versions for publication + removing unnecessary crates from publication * Remove OOD info from publishing sdk guide * rename contract imports + remove package * temp commit: continuing with removal of path from cargo manifest and replacing with workspace version import for publication * continuing with cargo.toml updates * dryrun only erroring on known version problem crates * remove old published-crates file * Minor comment change * remove default features warning * Additional info on workspace dep comment re publish list * Add missing description to cargo.toml * Fix missing feature flags * Add missing descriptions * Fix remaining path import * Add workspace repo / homepage / documentation links to cargo.toml files * remove workspace version from excluded crate * Remove todo descriptions * Minor comment change * add homepage etc * move from bls git import to nym_bls_fork crate * Modify rest of imports from path to workspace import, excluding binaries * add directory/homepage info * fix cargo fmt * add notes to gitignore * better solution to contracts/ experiment * wasm -> nym_wasm crate renaming * fix fatfinger * add metadata to ecash cargo.toml * stub publishing guide * fix misrevolved netlink- version * Fixes and block publication of rebase re: LP * first pass @ workflows
129 lines
3.5 KiB
Rust
129 lines
3.5 KiB
Rust
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use crate::bte::{CHUNK_BYTES, NUM_CHUNKS, SCALAR_SIZE};
|
|
use crate::error::DkgError;
|
|
use crate::interpolation::perform_lagrangian_interpolation_at_origin;
|
|
use crate::NodeIndex;
|
|
use nym_bls12_381_fork::Scalar;
|
|
use zeroize::{Zeroize, ZeroizeOnDrop};
|
|
|
|
// if this type is changed, one must ensure all values can fit in it
|
|
pub type Chunk = u16;
|
|
|
|
#[derive(PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
|
|
#[cfg_attr(test, derive(Clone))]
|
|
pub struct Share(pub(crate) Scalar);
|
|
|
|
pub fn combine_shares(shares: Vec<Share>, node_indices: &[NodeIndex]) -> Result<Scalar, DkgError> {
|
|
if shares.len() != node_indices.len() {
|
|
return Err(DkgError::MismatchedLagrangianSamplesLengths {
|
|
x: node_indices.len(),
|
|
y: shares.len(),
|
|
});
|
|
}
|
|
|
|
let samples = shares
|
|
.into_iter()
|
|
.zip(node_indices.iter())
|
|
.map(|(share, index)| (Scalar::from(*index), share.0))
|
|
.collect::<Vec<_>>();
|
|
|
|
perform_lagrangian_interpolation_at_origin(&samples)
|
|
}
|
|
|
|
impl Share {
|
|
// not really used outside tests
|
|
#[cfg(test)]
|
|
pub(crate) fn random(mut rng: impl rand_core::RngCore) -> Self {
|
|
use ff::Field;
|
|
Share(Scalar::random(&mut rng))
|
|
}
|
|
|
|
pub(crate) fn to_chunks(&self) -> ChunkedShare {
|
|
let mut chunks = [0; NUM_CHUNKS];
|
|
let mut bytes = self.0.to_bytes();
|
|
|
|
for (chunk, chunk_bytes) in chunks.iter_mut().zip(bytes[..].chunks_exact(CHUNK_BYTES)) {
|
|
let mut tmp = [0u8; CHUNK_BYTES];
|
|
tmp.copy_from_slice(chunk_bytes);
|
|
*chunk = Chunk::from_le_bytes(tmp)
|
|
}
|
|
|
|
bytes.zeroize();
|
|
ChunkedShare { chunks }
|
|
}
|
|
|
|
pub(crate) fn inner(&self) -> &Scalar {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl From<Scalar> for Share {
|
|
fn from(s: Scalar) -> Self {
|
|
Share(s)
|
|
}
|
|
}
|
|
|
|
#[derive(Default, Zeroize, ZeroizeOnDrop)]
|
|
#[cfg_attr(test, derive(Clone))]
|
|
pub(crate) struct ChunkedShare {
|
|
pub(crate) chunks: [Chunk; NUM_CHUNKS],
|
|
}
|
|
|
|
impl From<Share> for ChunkedShare {
|
|
fn from(share: Share) -> ChunkedShare {
|
|
share.to_chunks()
|
|
}
|
|
}
|
|
|
|
impl TryFrom<ChunkedShare> for Share {
|
|
type Error = DkgError;
|
|
|
|
fn try_from(chunked: ChunkedShare) -> Result<Share, Self::Error> {
|
|
let mut bytes = [0u8; SCALAR_SIZE];
|
|
for (chunk, chunk_bytes) in chunked
|
|
.chunks
|
|
.iter()
|
|
.zip(bytes[..].chunks_exact_mut(CHUNK_BYTES))
|
|
{
|
|
let tmp = chunk.to_le_bytes();
|
|
chunk_bytes.copy_from_slice(&tmp[..]);
|
|
}
|
|
|
|
let recovered = Option::from(Scalar::from_bytes(&bytes))
|
|
.map(Share)
|
|
.ok_or(DkgError::MalformedShare)?;
|
|
|
|
bytes.zeroize();
|
|
Ok(recovered)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::utils::combine_scalar_chunks;
|
|
use rand_core::SeedableRng;
|
|
|
|
#[test]
|
|
fn chunking_share() {
|
|
let dummy_seed = [1u8; 32];
|
|
let mut rng = rand_chacha::ChaCha20Rng::from_seed(dummy_seed);
|
|
|
|
let share = Share::random(&mut rng);
|
|
let chunks: ChunkedShare = share.clone().into();
|
|
|
|
let scalar_chunks = chunks
|
|
.chunks
|
|
.iter()
|
|
.map(|c| Scalar::from(*c as u64))
|
|
.collect::<Vec<_>>();
|
|
let expected = combine_scalar_chunks(&scalar_chunks);
|
|
assert_eq!(expected, share.0);
|
|
|
|
let recombined: Share = chunks.try_into().unwrap();
|
|
assert_eq!(expected, recombined.0);
|
|
}
|
|
}
|