diff --git a/server/crates/arbiter-crypto/src/authn/v1.rs b/server/crates/arbiter-crypto/src/authn/v1.rs index 6f38e44..6f86936 100644 --- a/server/crates/arbiter-crypto/src/authn/v1.rs +++ b/server/crates/arbiter-crypto/src/authn/v1.rs @@ -8,6 +8,7 @@ use rand::RngExt; pub static CLIENT_CONTEXT: &[u8] = b"arbiter_client"; pub static OPERATOR_CONTEXT: &[u8] = b"arbiter_operator"; +pub static GOVERNANCE_CONTEXT: &[u8] = b"arbiter_governance_vote"; const NONCE_SIZE: usize = 32; @@ -90,6 +91,11 @@ impl PublicKey { self.0 .verify_with_context(&challenge, context, &signature.0) } + + #[must_use] + pub fn verify_message(&self, message: &[u8], context: &[u8], signature: &Signature) -> bool { + self.0.verify_with_context(message, context, &signature.0) + } } impl Signature { diff --git a/server/crates/arbiter-server/src/actors/vault_coordinator/mod.rs b/server/crates/arbiter-server/src/actors/vault_coordinator/mod.rs index 68a8f95..107ab3e 100644 --- a/server/crates/arbiter-server/src/actors/vault_coordinator/mod.rs +++ b/server/crates/arbiter-server/src/actors/vault_coordinator/mod.rs @@ -9,7 +9,7 @@ use tracing::error; use crate::{ actors::vault::{Bootstrap, TryUnseal, Vault}, - crypto::{KeyCell, derive_key, encryption::v1::Nonce, shamir}, + crypto::{KeyCell, derive_key, encryption::v1::Nonce, shamir, shamir::shamir_threshold}, db::{self, models, schema}, }; @@ -76,15 +76,6 @@ impl VaultCoordinator { const SHARE_AAD: &[u8] = b"arbiter/shamir-share/v1"; -const fn shamir_threshold(n: usize) -> usize { - match n { - 0 => panic!("No operators"), - 1 => 1, - 2 => 2, - n => n / 2 + 1, - } -} - async fn finalize_bootstrap( db: db::DatabasePool, vault: ActorRef, diff --git a/server/crates/arbiter-server/src/crypto/shamir.rs b/server/crates/arbiter-server/src/crypto/shamir.rs index c379685..61c59e1 100644 --- a/server/crates/arbiter-server/src/crypto/shamir.rs +++ b/server/crates/arbiter-server/src/crypto/shamir.rs @@ -20,6 +20,18 @@ pub fn split_key( .map_err(|e| ShamirError::Split(format!("{e:?}"))) } +/// Returns the minimum number of shares required to reconstruct the secret +/// for a committee of `n` operators. +#[must_use] +pub const fn shamir_threshold(n: usize) -> usize { + match n { + 0 => panic!("No operators"), + 1 => 1, + 2 => 2, + n => n / 2 + 1, + } +} + /// Reconstruct the secret from `threshold` or more shares. pub fn combine_shares(shares: &[Vec]) -> Result<[u8; 32], ShamirError> { let bytes = Gf256::combine_array(shares)