pub mod errors;
pub mod execute_protocol;
mod listener;
mod protocol_message;
pub mod protocol_transport;
pub mod sign_and_encrypt;
pub use entropy_shared::user::ValidatorInfo;
pub use listener::Listener;
pub use protocol_message::ProtocolMessage;
extern crate alloc;
use std::{
fmt,
hash::{Hash, Hasher},
};
use blake2::{Blake2s256, Digest};
use errors::{ProtocolExecutionErr, VerifyingKeyError};
use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer};
use sp_core::{sr25519, Pair};
use subxt::utils::AccountId32;
use synedrion::{
ecdsa::VerifyingKey,
k256::{
ecdsa::{RecoveryId, Signature},
EncodedPoint,
},
signature::{self, hazmat::PrehashVerifier},
AuxInfo, ThresholdKeyShare,
};
pub const PROTOCOL_MESSAGE_VERSION: u32 = 1;
pub const SUPPORTED_PROTOCOL_MESSAGE_VERSIONS: [u32; 1] = [PROTOCOL_MESSAGE_VERSION];
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct PartyId(AccountId32);
impl std::hash::Hash for PartyId {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.0 .0.hash(state);
}
}
impl PartyId {
pub fn new(acc: AccountId32) -> Self {
Self(acc)
}
fn to_public(&self) -> sr25519::Public {
sr25519::Public(self.0 .0)
}
}
impl From<sr25519::Public> for PartyId {
fn from(public_key: sr25519::Public) -> Self {
Self(AccountId32(public_key.0))
}
}
impl PrehashVerifier<sr25519::Signature> for PartyId {
fn verify_prehash(
&self,
prehash: &[u8],
signature: &sr25519::Signature,
) -> Result<(), signature::Error> {
if sr25519::Pair::verify(signature, prehash, &self.to_public()) {
Ok(())
} else {
Err(signature::Error::new())
}
}
}
impl From<PartyId> for String {
fn from(party_id: PartyId) -> Self {
let bytes: &[u8] = party_id.0.as_ref();
hex::encode(bytes)
}
}
impl TryFrom<String> for PartyId {
type Error = String;
fn try_from(s: String) -> Result<Self, Self::Error> {
let bytes = hex::decode(s).map_err(|err| format!("{err}"))?;
let len = bytes.len();
let arr: [u8; 32] =
bytes.try_into().map_err(|_err| format!("Invalid party ID length: {}", len))?;
let acc = arr.into();
Ok(Self(acc))
}
}
impl fmt::Display for PartyId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
let bytes: &[u8] = self.0.as_ref();
write!(f, "PartyId({})", hex::encode(&bytes[0..4]))
}
}
#[cfg(not(test))]
use synedrion::ProductionParams;
#[cfg(not(test))]
pub type KeyParams = ProductionParams;
#[cfg(test)]
use synedrion::TestParams;
#[cfg(test)]
pub type KeyParams = TestParams;
pub use synedrion::KeyShare;
pub type KeyShareWithAuxInfo = (ThresholdKeyShare<KeyParams, PartyId>, AuxInfo<KeyParams, PartyId>);
#[derive(Clone, Debug)]
pub struct RecoverableSignature {
pub signature: Signature,
pub recovery_id: RecoveryId,
}
impl Serialize for RecoverableSignature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut state = serializer.serialize_struct("RecoverableSignature", 2)?;
state.serialize_field("signature", &self.signature)?;
state.serialize_field("recovery_id", &self.recovery_id.to_byte())?;
state.end()
}
}
impl RecoverableSignature {
pub fn to_rsv_bytes(&self) -> [u8; 65] {
let mut res = [0u8; 65];
let rs = self.signature.to_bytes();
res[0..64].copy_from_slice(&rs);
res[64] = self.recovery_id.to_byte();
res
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub enum SessionId {
Dkg { block_number: u32 },
Reshare { verifying_key: Vec<u8>, block_number: u32 },
Sign(SigningSessionInfo),
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct SigningSessionInfo {
pub signature_verifying_key: Vec<u8>,
pub message_hash: [u8; 32],
pub request_author: AccountId32,
}
impl Hash for SessionId {
fn hash<H: Hasher>(&self, state: &mut H) {
match self {
SessionId::Dkg { block_number } => {
block_number.hash(state);
},
SessionId::Reshare { verifying_key, block_number } => {
verifying_key.hash(state);
block_number.hash(state);
},
SessionId::Sign(signing_session_info) => {
signing_session_info.signature_verifying_key.hash(state);
signing_session_info.message_hash.hash(state);
signing_session_info.request_author.0.hash(state);
},
}
}
}
impl SessionId {
pub fn blake2(
&self,
sub_session: Option<Subsession>,
) -> Result<[u8; 32], ProtocolExecutionErr> {
let mut hasher = Blake2s256::new();
hasher.update(bincode::serialize(self)?);
if let Some(session) = sub_session {
hasher.update(format!("{:?}", session).as_bytes());
}
Ok(hasher.finalize().into())
}
}
#[derive(Debug)]
pub enum Subsession {
KeyInit,
Reshare,
AuxGen,
}
pub fn decode_verifying_key(
verifying_key_encoded: &[u8; 33],
) -> Result<VerifyingKey, VerifyingKeyError> {
let point = EncodedPoint::from_bytes(verifying_key_encoded)
.map_err(|_| VerifyingKeyError::DecodeEncodedPoint)?;
VerifyingKey::from_encoded_point(&point)
.map_err(|_| VerifyingKeyError::EncodedPointToVerifyingKey)
}