confium_tc_frost_ml_dsa_65/
lib.rs1#![forbid(unsafe_code)]
10#![allow(missing_docs)] use serde::{Deserialize, Serialize};
13
14pub const ALGORITHM: &str = "FROST-ML-DSA-65";
16
17pub const PUBLIC_KEY_SIZE: usize = 1952;
19
20pub const SIGNATURE_SIZE: usize = 3309;
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct ThresholdPublicKey {
26 pub bytes: Vec<u8>,
28}
29
30#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct Share {
33 pub party_index: u32,
35 pub bytes: Vec<u8>,
37}
38
39#[derive(Debug, thiserror::Error)]
41pub enum FrostMlDsaError {
42 #[error("threshold not met: have {have}, need {need}")]
44 ThresholdNotMet {
45 have: usize,
47 need: u32,
49 },
50 #[error("operation requires academic collaborator: {0}")]
52 ResearchOnly(String),
53}
54
55pub fn validate_public_key(pk: &ThresholdPublicKey) -> Result<(), FrostMlDsaError> {
57 if pk.bytes.len() != PUBLIC_KEY_SIZE {
58 return Err(FrostMlDsaError::ResearchOnly(format!(
59 "expected public key length {PUBLIC_KEY_SIZE}, got {}",
60 pk.bytes.len()
61 )));
62 }
63 Ok(())
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn algorithm_id() {
72 assert_eq!(ALGORITHM, "FROST-ML-DSA-65");
73 }
74
75 #[test]
76 fn validate_correct_size() {
77 let pk = ThresholdPublicKey {
78 bytes: vec![0u8; PUBLIC_KEY_SIZE],
79 };
80 validate_public_key(&pk).unwrap();
81 }
82
83 #[test]
84 fn validate_wrong_size_fails() {
85 let pk = ThresholdPublicKey {
86 bytes: vec![0u8; 100],
87 };
88 let result = validate_public_key(&pk);
89 assert!(matches!(result, Err(FrostMlDsaError::ResearchOnly(_))));
90 }
91}