confium_tc_cmp20/lib.rs
1#![allow(rustdoc::broken_intra_doc_links)]
2#![allow(rustdoc::bare_urls)]
3#![allow(rustdoc::redundant_explicit_links)]
4#![allow(rustdoc::private_intra_doc_links)]
5#![allow(rustdoc::invalid_html_tags)]
6
7//! CMP20 threshold ECDSA over P-256 (Canetti, Makriyannis, Peled 2020,
8//! eprint 2020/496).
9//!
10//! A newer, more efficient threshold ECDSA protocol than GG18. Key
11//! improvements exploited here:
12//!
13//! - **Non-interactive key generation** — DKG collapses to a single
14//! broadcast round (each party commits its public share; no per-peer
15//! share exchange is needed in the simplified path).
16//! - **Three-round signing** — down from GG18's four. Round 1 commits
17//! nonces, round 2 reveals them and carries the MtA products, round 3
18//! posts partial signatures and combines in the same round.
19//! - **Identifiable abort** — when a partial signature fails to verify
20//! the offending party is reported by index rather than failing
21//! opaquely.
22//!
23//! # Example
24//!
25//! ```
26//! use confium_tc_cmp20::inprocess;
27//!
28//! // 2-of-3 DKG: produces 3 share blobs + a joint P-256 public key.
29//! let kg = inprocess::keygen(2, 3)?;
30//!
31//! // Sign with the first 2 shares (threshold met).
32//! let sig = inprocess::sign(&kg.shares[..2], 2, b"hello, threshold world")?;
33//! assert_eq!(sig.len(), 64); // (r, s) pair
34//! # Ok::<(), confium_tc::Error>(())
35//! ```
36//!
37//! Wired as a [`confium_tc::registry::TcScheme`] plugin with two scheme
38//! names registered through [`confium_tc::register_tc_scheme!`]:
39//!
40//! - [`DKG_SCHEME_NAME`] = `"CMP20-ECDSA-P256"` (non-interactive DKG) —
41//! produces per-party [`Cmp20Share`] + shared public key.
42//! - [`SIGN_SCHEME_NAME`] = `"CMP20-ECDSA-P256-SIGN"` — produces a
43//! standard 64-byte `(r, s)` ECDSA signature verifiable with the
44//! `p256` crate.
45//!
46//! See the module-level docs of [`keygen`], [`sign`], [`mta`] for what
47//! is implemented and what is omitted. In short: the Feldman VSS,
48//! Lagrange interpolation, and threshold-ECDSA combine are all real;
49//! the MtA sub-round is a simplified in-process stub (products computed
50//! in the clear) rather than a Paillier-based homomorphic MtA, matching
51//! the GG18 crate's deferred-Paillier approach.
52
53pub mod e2e_signing;
54pub mod error;
55pub mod gg18_e2e;
56pub mod gg18_mta;
57pub mod inprocess;
58pub mod keygen;
59pub mod lagrange;
60pub mod mta;
61pub mod mta_proofs;
62pub mod paillier_mta;
63pub mod recovery;
64pub mod refresh;
65pub mod scheme;
66pub mod share;
67pub mod sign;
68pub mod vss;
69
70#[cfg(test)]
71mod props;
72
73pub use scheme::{Cmp20EcdsaP256, Cmp20EcdsaP256Sign};
74pub use share::Cmp20Share;
75
76/// Canonical scheme name for CMP20 DKG over P-256.
77pub const DKG_SCHEME_NAME: &str = "CMP20-ECDSA-P256";
78
79/// Canonical scheme name for CMP20 signing over P-256.
80pub const SIGN_SCHEME_NAME: &str = "CMP20-ECDSA-P256-SIGN";