Skip to content

Commit

Permalink
tests: add test for kel with witness
Browse files Browse the repository at this point in the history
  • Loading branch information
edytapawlak committed Mar 20, 2024
1 parent aaf521f commit 3923e06
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 2 deletions.
2 changes: 1 addition & 1 deletion components/controller/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repository.workspace = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
async-std = { version = "1.12.0", features = ["attributes"] }
async-std = { version = "1.12.0", features = ["attributes", "tokio1"] }
futures = "0.3.24"
keri-core = { path = "../../keriox_core", version = "0.9.0", features = ["oobi", "mailbox"] }
teliox = {path = "../../support/teliox", version = "0.2.0" }
Expand Down
4 changes: 3 additions & 1 deletion components/controller/src/identifier_controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,9 @@ impl IdentifierController {
.map(|sig| {
(
sig,
(state.iter().position(|bp| bp.verify(data, sig).ok().is_some())),
(state
.iter()
.position(|bp| bp.verify(data, sig).ok().is_some())),
)
})
.map(|(sig, index)| {
Expand Down
139 changes: 139 additions & 0 deletions keriox_tests/tests/test_kel_with_witness.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use std::sync::Arc;

use keri_controller::{
config::ControllerConfig, error::ControllerError, identifier_controller::IdentifierController,
BasicPrefix, Controller, CryptoBox, KeyManager, LocationScheme, SelfSigningPrefix,
};
use tempfile::Builder;

#[async_std::test]
async fn test_kel_with_witness() -> Result<(), ControllerError> {
let first_witness_id: BasicPrefix = "BDg3H7Sr-eES0XWXiO8nvMxW6mD_1LxLeE1nuiZxhGp4"
.parse()
.unwrap();
// OOBI (Out-Of-Band Introduction) specifies the way how actors can be found.
let first_witness_oobi: LocationScheme = serde_json::from_str(&format!(
r#"{{"eid":{:?},"scheme":"http","url":"http://witness2.sandbox.argo.colossi.network/"}}"#,
first_witness_id
))
.unwrap();

let second_witness_id: BasicPrefix = "BDg1zxxf8u4Hx5IPraZzmStfSCZFZbDzMHjqVcFW5OfP"
.parse()
.unwrap();
let second_witness_oobi: LocationScheme = serde_json::from_str(&format!(
r#"{{"eid":{:?},"scheme":"http","url":"http://witness3.sandbox.argo.colossi.network/"}}"#,
second_witness_id
))
.unwrap();

// Setup database path and key manager.
let database_path = Builder::new().prefix("test-db0").tempdir().unwrap();
let mut key_manager = CryptoBox::new().unwrap();

let controller = Arc::new(Controller::new(ControllerConfig {
db_path: database_path.path().to_owned(),
..Default::default()
})?);

let actor = {
let pk = BasicPrefix::Ed25519(key_manager.public_key());
let npk = BasicPrefix::Ed25519(key_manager.next_public_key());

// Create inception event, that needs one witness receipt to be accepted.
let icp_event = controller
.incept(
vec![pk],
vec![npk],
vec![first_witness_oobi, second_witness_oobi],
1,
)
.await?;
let signature =
SelfSigningPrefix::Ed25519Sha512(key_manager.sign(icp_event.as_bytes()).unwrap());

let identifier = controller
.finalize_inception(icp_event.as_bytes(), &signature)
.await?;
IdentifierController::new(identifier, controller.clone(), None)
};

// Trying to get current actor event seal.
let inception_event_seal = actor.get_last_establishment_event_seal();

// It fails because witness receipts are missing.
assert!(matches!(
inception_event_seal,
Err(ControllerError::UnknownIdentifierError)
));

// Publish event to actor's witnesses
actor.notify_witnesses().await.unwrap();

// Querying witness to get receipts
for qry in actor
.query_mailbox(&actor.id, &[first_witness_id.clone()])
.unwrap()
{
let signature =
SelfSigningPrefix::Ed25519Sha512(key_manager.sign(&qry.encode().unwrap()).unwrap());
actor.finalize_query(vec![(qry, signature)]).await.unwrap();
}

// Now KEL event should be accepted and event seal exists.
let inception_event_seal = actor.get_last_establishment_event_seal();
assert!(inception_event_seal.is_ok());

// Rotate keys
key_manager.rotate()?;
let pk = BasicPrefix::Ed25519(key_manager.public_key());
let npk = BasicPrefix::Ed25519(key_manager.next_public_key());

// Rotation needs two witness receipts to be accepted
let rotation_event = actor.rotate(vec![pk], vec![npk], vec![], vec![], 2).await?;

let signature = SelfSigningPrefix::Ed25519Sha512(key_manager.sign(rotation_event.as_bytes())?);
actor
.finalize_event(rotation_event.as_bytes(), signature)
.await?;

// Trying to verify message signed with rotated keys.
let message = "Hi".as_bytes();
let first_message_signature = vec![SelfSigningPrefix::Ed25519Sha512(
key_manager.sign(message).unwrap(),
)];

let current_event_seal = actor.get_last_establishment_event_seal()?;
let signature =
actor.transferable_signature(message, current_event_seal, &first_message_signature)?;

// Verification fails. Rotation wasn't accepted into KEL because of lack of
// witness receipts. Current event seal points to inception event so old
// public keys was used for verification.
assert!(matches!(
controller.verify(message, &signature).unwrap_err(),
ControllerError::FaultySignature
));

// Publish event to actor's witnesses
actor.notify_witnesses().await.unwrap();

// Querying witnesses to get receipts
for qry in actor
.query_mailbox(&actor.id, &[first_witness_id, second_witness_id])
.unwrap()
{
let signature =
SelfSigningPrefix::Ed25519Sha512(key_manager.sign(&qry.encode().unwrap()).unwrap());
actor.finalize_query(vec![(qry, signature)]).await.unwrap();
}

// Update signature and verify again
let current_event_seal = actor.get_last_establishment_event_seal()?;
let signature =
actor.transferable_signature(message, current_event_seal, &first_message_signature)?;

assert!(controller.verify(message, &signature).is_ok());

Ok(())
}

0 comments on commit 3923e06

Please sign in to comment.