use crate::{
error::Error,
event::Event,
prefix::{attached_signature::get_sig_count, AttachedSignaturePrefix, BasicPrefix, Prefix},
state::{EventSemantics, IdentifierState, Verifiable},
util::dfs_serializer,
};
pub mod serialization_info;
use core::str::FromStr;
use serde::{Deserialize, Serialize};
use serialization_info::*;
use std::convert::TryInto;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EventMessage {
#[serde(rename = "vs")]
serialization_info: SerializationInfo,
#[serde(flatten)]
pub event: Event,
}
pub struct SignedEventMessage {
pub event_message: EventMessage,
pub signatures: Vec<AttachedSignaturePrefix>,
}
impl EventMessage {
pub fn new(event: &Event, format: &SerializationFormats) -> Result<Self, Error> {
Ok(Self {
serialization_info: SerializationInfo {
major_version: 1,
minor_version: 0,
size: Self::get_size(event, format)? as u16,
kind: *format,
},
event: event.clone(),
})
}
fn get_size(event: &Event, format: &SerializationFormats) -> Result<usize, Error> {
Ok(Self {
serialization_info: SerializationInfo::new(format, 0),
event: event.clone(),
}
.serialize()
.map_err(|_| Error::DeserializationError)?
.len())
}
pub fn serialization(&self) -> SerializationFormats {
self.serialization_info.kind
}
pub fn serialize(&self) -> Result<Vec<u8>, Error> {
self.serialization().encode(self)
}
pub fn extract_serialized_data_set(&self) -> Result<String, Error> {
dfs_serializer::to_string(self)
}
pub fn sign(&self, sigs: Vec<AttachedSignaturePrefix>) -> SignedEventMessage {
SignedEventMessage::new(self, sigs)
}
}
impl SignedEventMessage {
pub fn new(message: &EventMessage, sigs: Vec<AttachedSignaturePrefix>) -> Self {
Self {
event_message: message.clone(),
signatures: sigs,
}
}
}
impl EventSemantics for EventMessage {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
self.event.apply_to(state)
}
}
impl EventSemantics for SignedEventMessage {
fn apply_to(&self, state: IdentifierState) -> Result<IdentifierState, Error> {
self.event_message.apply_to(state)
}
}
impl Verifiable for SignedEventMessage {
fn verify_against(&self, state: &IdentifierState) -> Result<bool, Error> {
let serialized_data_extract = self.event_message.extract_serialized_data_set()?;
Ok(self.signatures.len() as u64 >= state.current.threshold
&& self
.signatures
.iter()
.fold(Ok(true), |acc: Result<bool, Error>, sig| {
Ok(acc?
&& state
.current
.signers
.get(sig.index as usize)
.ok_or(Error::SemanticError("Key not present in state".to_string()))
.and_then(|key: &BasicPrefix| {
key.verify(serialized_data_extract.as_bytes(), &sig.sig)
})?)
})?)
}
}
const JSON_SIG_DELIMITER: &str = "\n";
pub fn parse_signed_message_json(message: &str) -> Result<SignedEventMessage, Error> {
let parts: Vec<&str> = message.split(JSON_SIG_DELIMITER).collect();
let sigs: Vec<AttachedSignaturePrefix> = parts[2..]
.iter()
.map(|sig| AttachedSignaturePrefix::from_str(sig))
.collect::<Result<Vec<AttachedSignaturePrefix>, Error>>()?;
Ok(SignedEventMessage {
event_message: serde_json::from_str(parts[0])?,
signatures: sigs,
})
}
pub fn serialize_signed_message_json(message: &SignedEventMessage) -> Result<String, Error> {
Ok([
serde_json::to_string(&message.event_message)?,
get_sig_count(message.signatures.len().try_into().unwrap()),
message
.signatures
.iter()
.map(|sig| sig.to_str())
.collect::<Vec<String>>()
.join(JSON_SIG_DELIMITER),
]
.join(JSON_SIG_DELIMITER))
}
pub fn validate_events(kel: &[SignedEventMessage]) -> Result<IdentifierState, Error> {
kel.iter().fold(Ok(IdentifierState::default()), |s, e| {
s?.verify_and_apply(e)
})
}
#[cfg(test)]
mod tests {
use super::super::util::dfs_serializer;
use super::*;
use crate::{
derivation::{blake2b_256_digest, sha3_512_digest},
event::{
event_data::{inception::InceptionEvent, EventData},
sections::InceptionWitnessConfig,
sections::KeyConfig,
},
prefix::{
AttachedSignaturePrefix, BasicPrefix, IdentifierPrefix, SelfAddressingPrefix,
SelfSigningPrefix,
},
};
use serde_json;
use ursa::{
kex::{x25519, KeyExchangeScheme},
signatures::{ed25519, SignatureScheme},
};
#[test]
fn basic_create() -> Result<(), Error> {
let ed = ed25519::Ed25519Sha512::new();
let (pub_key0, priv_key0) = ed
.keypair(Option::None)
.map_err(|e| Error::CryptoError(e))?;
let (pub_key1, _priv_key1) = ed
.keypair(Option::None)
.map_err(|e| Error::CryptoError(e))?;
let pref0 = BasicPrefix::Ed25519(pub_key0);
let pref1 = SelfAddressingPrefix::SHA3_512(sha3_512_digest(&pub_key1.0));
let icp = Event {
prefix: IdentifierPrefix::Basic(pref0.clone()),
sn: 0,
event_data: EventData::Icp(InceptionEvent {
key_config: KeyConfig {
threshold: 1,
public_keys: vec![pref0.clone()],
threshold_key_digest: pref1.clone(),
},
witness_config: InceptionWitnessConfig::default(),
inception_configuration: vec![],
}),
};
let icp_m = icp.to_message(&SerializationFormats::JSON)?;
let sed = icp_m.extract_serialized_data_set()?;
let sig = ed
.sign(sed.as_bytes(), &priv_key0)
.map_err(|e| Error::CryptoError(e))?;
let attached_sig = AttachedSignaturePrefix {
index: 0,
sig: SelfSigningPrefix::Ed25519Sha512(sig),
};
assert!(pref0.verify(sed.as_bytes(), &attached_sig.sig)?);
let signed_event = icp_m.sign(vec![attached_sig]);
let s_ = IdentifierState::default();
let s0 = s_.verify_and_apply(&signed_event)?;
assert_eq!(s0.prefix, IdentifierPrefix::Basic(pref0.clone()));
assert_eq!(s0.sn, 0);
assert_eq!(s0.last, SelfAddressingPrefix::default());
assert_eq!(s0.current.signers.len(), 1);
assert_eq!(s0.current.signers[0], pref0);
assert_eq!(s0.current.threshold, 1);
assert_eq!(s0.next, pref1);
assert_eq!(s0.witnesses, vec![]);
assert_eq!(s0.tally, 0);
assert_eq!(s0.delegated_keys, vec![]);
Ok(())
}
#[test]
fn self_addressing_create() -> Result<(), Error> {
let ed = ed25519::Ed25519Sha512::new();
let (sig_key_0, sig_priv_0) = ed
.keypair(Option::None)
.map_err(|e| Error::CryptoError(e))?;
let (sig_key_1, sig_priv_1) = ed
.keypair(Option::None)
.map_err(|e| Error::CryptoError(e))?;
let x = x25519::X25519Sha256::new();
let (enc_key_0, enc_priv_0) = x.keypair(Option::None).map_err(|e| Error::CryptoError(e))?;
let (enc_key_1, enc_priv_1) = x.keypair(Option::None).map_err(|e| Error::CryptoError(e))?;
let sig_pref_0 = BasicPrefix::Ed25519(sig_key_0);
let enc_pref_0 = BasicPrefix::X25519(enc_key_0);
let sig_pref_1 = BasicPrefix::Ed25519(sig_key_1);
let enc_pref_1 = BasicPrefix::X25519(enc_key_1);
let nexter_pref = SelfAddressingPrefix::Blake2B256(blake2b_256_digest(
[sig_pref_1.to_str(), enc_pref_1.to_str()]
.join("")
.as_bytes(),
));
let icp_data = Event {
prefix: IdentifierPrefix::default(),
sn: 0,
event_data: EventData::Icp(InceptionEvent {
key_config: KeyConfig {
threshold: 1,
public_keys: vec![sig_pref_0.clone(), enc_pref_0.clone()],
threshold_key_digest: nexter_pref.clone(),
},
witness_config: InceptionWitnessConfig::default(),
inception_configuration: vec![],
}),
};
let icp_data_message = icp_data.to_message(&SerializationFormats::JSON)?;
let pref = IdentifierPrefix::SelfAddressing(SelfAddressingPrefix::Blake2B256(
blake2b_256_digest(icp_data_message.extract_serialized_data_set()?.as_bytes()),
));
let icp_m = Event {
prefix: pref.clone(),
..icp_data
}
.to_message(&SerializationFormats::JSON)?;
let sed = icp_m.extract_serialized_data_set()?;
let sig = ed
.sign(sed.as_bytes(), &sig_priv_0)
.map_err(|e| Error::CryptoError(e))?;
let attached_sig = AttachedSignaturePrefix {
index: 0,
sig: SelfSigningPrefix::Ed25519Sha512(sig),
};
assert!(sig_pref_0.verify(sed.as_bytes(), &attached_sig.sig)?);
let signed_event = icp_m.sign(vec![attached_sig]);
let s_ = IdentifierState::default();
let s0 = s_.verify_and_apply(&signed_event)?;
assert_eq!(s0.prefix, pref);
assert_eq!(s0.sn, 0);
assert_eq!(s0.last, SelfAddressingPrefix::default());
assert_eq!(s0.current.signers.len(), 2);
assert_eq!(s0.current.signers[0], sig_pref_0);
assert_eq!(s0.current.signers[1], enc_pref_0);
assert_eq!(s0.current.threshold, 1);
assert_eq!(s0.next, nexter_pref);
assert_eq!(s0.witnesses, vec![]);
assert_eq!(s0.tally, 0);
assert_eq!(s0.delegated_keys, vec![]);
Ok(())
}
}