use std::sync::Arc;
use elliptic_curve::Group;
use rand::{CryptoRng, Rng, RngCore};
use thiserror::Error;
use sl_mpc_mate::math::Polynomial;
use crate::common::ser::Serializable;
#[cfg(feature = "serde")]
use crate::common::utils::serde_arc;
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct KeygenParams {
pub n: u8,
pub t: u8,
pub party_id: u8,
pub key_id: Option<[u8; 32]>,
#[cfg_attr(feature = "serde", serde(with = "serde_arc"))]
pub dec_key: Arc<crypto_box::SecretKey>,
pub party_enc_keys: Vec<(u8, crypto_box::PublicKey)>,
pub extra_data: Option<Vec<u8>>,
}
#[cfg_attr(
feature = "serde",
derive(serde::Serialize, serde::Deserialize),
serde(bound(serialize = "G: Group", deserialize = "G: Group"))
)]
pub struct KeyEntropy<G>
where
G: Group,
G::Scalar: Serializable,
{
pub session_id: [u8; 32],
pub(crate) polynomial: Polynomial<G>,
pub(crate) r_i: [u8; 32],
pub(crate) chain_code_id: [u8; 32],
}
impl<G> KeyEntropy<G>
where
G: Group,
G::Scalar: Serializable,
{
pub fn generate<R: CryptoRng + RngCore>(t: u8, rng: &mut R) -> Self {
let session_id = rng.gen();
let polynomial = Polynomial::random(rng, (t - 1) as usize);
KeyEntropy {
session_id,
polynomial,
r_i: rng.gen(),
chain_code_id: rng.gen(),
}
}
pub fn generate_refresh<R: CryptoRng + RngCore>(t: u8, rng: &mut R) -> Self {
let mut ent = Self::generate(t, rng);
ent.polynomial.reset_constant();
ent
}
}
#[derive(Debug, Error)]
pub enum KeygenError {
#[error("Invalid pid, it must be in the range [1,n]")]
InvalidPid,
#[error("Invalid message data")]
InvalidMsgData,
#[error("Invalid t, must be less than n")]
InvalidT,
#[error("Provided messages list has invalid length")]
InvalidMsgCount,
#[error("Incorrect participant pid's in the message list")]
InvalidParticipantSet,
#[error("Proof error")]
ProofError,
#[error("Decrypted d_i scalar cannot be deserialized")]
InvalidDiPlaintext,
#[error("Encryption Error")]
EncryptionError,
#[error("Decryption Error")]
DecryptionError,
#[error("Invalid signature")]
InvalidSignature,
#[error("Abort")]
Abort(&'static str),
#[error("Error during key refresh or recovery protocol")]
InvalidRefresh,
}