confium_tc_frost_ed25519/
inprocess.rs1use confium_tc::Result;
9use confium_tc::inprocess as driver;
10
11#[derive(Debug, Clone)]
13pub struct KeygenOutput {
14 pub shares: Vec<Vec<u8>>,
16 pub public_key: Vec<u8>,
18}
19
20pub fn keygen(threshold: u32, party_count: usize) -> Result<Vec<Vec<u8>>> {
23 driver::run_dkg(crate::DKG_SCHEME, threshold, party_count)
24}
25
26pub fn sign(share_blobs: &[Vec<u8>], threshold: u32, message: &[u8]) -> Result<Vec<u8>> {
29 driver::run_sign(crate::SIGN_SCHEME, share_blobs, threshold, message)
30}
31
32pub fn sign_batch(
34 share_blobs: &[Vec<u8>],
35 threshold: u32,
36 messages: &[&[u8]],
37) -> Result<Vec<Vec<u8>>> {
38 let mut out = Vec::with_capacity(messages.len());
39 for msg in messages {
40 out.push(sign(share_blobs, threshold, msg)?);
41 }
42 Ok(out)
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn dkg_and_sign_round_trip() {
51 let shares = keygen(2, 3).expect("dkg");
52 assert_eq!(shares.len(), 3);
53 let sig = sign(&shares[..2], 2, b"hello ed25519").expect("sign");
54 assert!(!sig.is_empty());
55 }
56
57 #[test]
58 fn below_threshold_errors() {
59 let shares = keygen(3, 5).expect("dkg");
60 assert!(sign(&shares[..2], 3, b"msg").is_err());
61 }
62
63 #[test]
64 fn sign_batch_produces_one_sig_per_message() {
65 let shares = keygen(2, 3).expect("dkg");
66 let messages: Vec<&[u8]> = vec![b"msg-a", b"msg-b", b"msg-c", b"msg-d"];
67 let sigs = sign_batch(&shares[..2], 2, &messages).expect("batch sign");
68 assert_eq!(sigs.len(), 4);
69 for s in &sigs {
70 assert!(!s.is_empty());
71 }
72 }
73
74 #[test]
75 fn sign_batch_empty_messages_returns_empty() {
76 let shares = keygen(2, 3).expect("dkg");
77 let sigs = sign_batch(&shares[..2], 2, &[]).expect("empty batch");
78 assert!(sigs.is_empty());
79 }
80
81 #[test]
82 fn sign_batch_propagates_signing_error() {
83 let shares = keygen(3, 5).expect("dkg");
84 let messages: Vec<&[u8]> = vec![b"a", b"b"];
86 let err = sign_batch(&shares[..2], 3, &messages);
87 assert!(err.is_err());
88 }
89}