//! Confidential Key Derivation (CKD) protocol. //! //! This module provides the implementation of the Confidential Key Derivation (CKD) protocol, //! which allows a client to derive a unique key for a specific application without revealing //! the application identifier to the key derivation service. //! //! The protocol is based on a combination of Oblivious Transfer (OT) and Diffie-Hellman key exchange. //! //! For more details, refer to the `confidential-key-derivation.md` document in the `docs` folder. pub mod app_id; pub mod ciphersuite; pub mod protocol; mod protocol_pv; mod scalar_wrapper; #[cfg(test)] mod test; use serde::{Deserialize, Serialize}; pub use app_id::AppId; pub use crate::confidential_key_derivation::ciphersuite::BLS12381SHA256; pub type Scalar = blstrs::Scalar; pub type ElementG1 = blstrs::G1Projective; pub type ElementG2 = blstrs::G2Projective; pub type KeygenOutput = crate::KeygenOutput; pub type SigningShare = crate::SigningShare; pub use protocol_pv::ckd as ckd_pv; /// The output of the confidential key derivation protocol when run by the coordinator #[derive(Debug, Clone, Deserialize, Serialize, derive_more::Constructor)] pub struct CKDOutput { big_y: ElementG1, big_c: ElementG1, } impl CKDOutput { /// Outputs `big_y` pub fn big_y(&self) -> ElementG1 { self.big_y } /// Outputs `big_c` pub fn big_c(&self) -> ElementG1 { self.big_c } /// Takes a secret scalar and returns /// s <- C − a ⋅ Y = msk ⋅ H ( `app_id` ) pub fn unmask(&self, secret_scalar: Scalar) -> Signature { self.big_c - self.big_y * secret_scalar } } /// None for participants and Some for coordinator pub type CKDOutputOption = Option; pub type VerifyingKey = crate::VerifyingKey; pub type PublicKey = ElementG1; pub type Signature = ElementG1; #[derive(Debug, Clone, Deserialize, Serialize, derive_more::Constructor)] pub struct PublicVerificationKey { pk1: ElementG1, pk2: ElementG2, } /// Hashes the app id and the public key as of /// H(pk || `app_id`) where H is a random oracle pub fn hash_app_id_with_pk(pk: &VerifyingKey, app_id: &[u8]) -> ElementG1 { let compressed_pk = pk.to_element().to_compressed(); let input = [compressed_pk.as_slice(), app_id].concat(); ciphersuite::hash_to_curve(&input) }