Skip to main content

ruvector_dag/qudag/crypto/
identity.rs

1//! QuDAG Identity Management
2
3use super::{
4    MlDsa65, MlDsa65PublicKey, MlDsa65SecretKey, MlKem768, MlKem768PublicKey, MlKem768SecretKey,
5};
6
7pub struct QuDagIdentity {
8    pub node_id: String,
9    pub kem_public: MlKem768PublicKey,
10    pub kem_secret: MlKem768SecretKey,
11    pub dsa_public: MlDsa65PublicKey,
12    pub dsa_secret: MlDsa65SecretKey,
13}
14
15impl QuDagIdentity {
16    pub fn generate() -> Result<Self, IdentityError> {
17        let (kem_public, kem_secret) =
18            MlKem768::generate_keypair().map_err(|_| IdentityError::KeyGenerationFailed)?;
19
20        let (dsa_public, dsa_secret) =
21            MlDsa65::generate_keypair().map_err(|_| IdentityError::KeyGenerationFailed)?;
22
23        // Generate node ID from public key hash
24        let node_id = Self::hash_to_id(&kem_public.0[..32]);
25
26        Ok(Self {
27            node_id,
28            kem_public,
29            kem_secret,
30            dsa_public,
31            dsa_secret,
32        })
33    }
34
35    pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, IdentityError> {
36        let sig =
37            MlDsa65::sign(&self.dsa_secret, message).map_err(|_| IdentityError::SigningFailed)?;
38        Ok(sig.0.to_vec())
39    }
40
41    pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool, IdentityError> {
42        if signature.len() != super::ml_dsa::ML_DSA_65_SIGNATURE_SIZE {
43            return Err(IdentityError::InvalidSignature);
44        }
45
46        let mut sig_array = [0u8; super::ml_dsa::ML_DSA_65_SIGNATURE_SIZE];
47        sig_array.copy_from_slice(signature);
48
49        MlDsa65::verify(
50            &self.dsa_public,
51            message,
52            &super::ml_dsa::Signature(sig_array),
53        )
54        .map_err(|_| IdentityError::VerificationFailed)
55    }
56
57    pub fn encrypt_for(
58        &self,
59        recipient_pk: &[u8],
60        plaintext: &[u8],
61    ) -> Result<Vec<u8>, IdentityError> {
62        if recipient_pk.len() != super::ml_kem::ML_KEM_768_PUBLIC_KEY_SIZE {
63            return Err(IdentityError::InvalidPublicKey);
64        }
65
66        let mut pk_array = [0u8; super::ml_kem::ML_KEM_768_PUBLIC_KEY_SIZE];
67        pk_array.copy_from_slice(recipient_pk);
68
69        let encap = MlKem768::encapsulate(&MlKem768PublicKey(pk_array))
70            .map_err(|_| IdentityError::EncryptionFailed)?;
71
72        // Simple XOR encryption with shared secret
73        let mut ciphertext = encap.ciphertext.to_vec();
74        for (i, byte) in plaintext.iter().enumerate() {
75            ciphertext.push(*byte ^ encap.shared_secret[i % 32]);
76        }
77
78        Ok(ciphertext)
79    }
80
81    pub fn decrypt(&self, ciphertext: &[u8]) -> Result<Vec<u8>, IdentityError> {
82        if ciphertext.len() < super::ml_kem::ML_KEM_768_CIPHERTEXT_SIZE {
83            return Err(IdentityError::InvalidCiphertext);
84        }
85
86        let mut ct_array = [0u8; super::ml_kem::ML_KEM_768_CIPHERTEXT_SIZE];
87        ct_array.copy_from_slice(&ciphertext[..super::ml_kem::ML_KEM_768_CIPHERTEXT_SIZE]);
88
89        let shared_secret = MlKem768::decapsulate(&self.kem_secret, &ct_array)
90            .map_err(|_| IdentityError::DecryptionFailed)?;
91
92        // Decrypt with XOR
93        let encrypted_data = &ciphertext[super::ml_kem::ML_KEM_768_CIPHERTEXT_SIZE..];
94        let plaintext: Vec<u8> = encrypted_data
95            .iter()
96            .enumerate()
97            .map(|(i, &b)| b ^ shared_secret[i % 32])
98            .collect();
99
100        Ok(plaintext)
101    }
102
103    fn hash_to_id(data: &[u8]) -> String {
104        let hash: u64 = data
105            .iter()
106            .fold(0u64, |acc, &b| acc.wrapping_mul(31).wrapping_add(b as u64));
107        format!("qudag_{:016x}", hash)
108    }
109}
110
111#[derive(Debug, thiserror::Error)]
112pub enum IdentityError {
113    #[error("Key generation failed")]
114    KeyGenerationFailed,
115    #[error("Signing failed")]
116    SigningFailed,
117    #[error("Verification failed")]
118    VerificationFailed,
119    #[error("Invalid signature")]
120    InvalidSignature,
121    #[error("Invalid public key")]
122    InvalidPublicKey,
123    #[error("Encryption failed")]
124    EncryptionFailed,
125    #[error("Decryption failed")]
126    DecryptionFailed,
127    #[error("Invalid ciphertext")]
128    InvalidCiphertext,
129}