cait_sith/lib.rs
1//! Cait-Sith is a novel threshold ECDSA protocol (and implementation),
2//! which is both simpler and substantially more performant than
3//! popular alternatives.
4//!
5//! The protocol supports arbitrary numbers of parties and thresholds.
6//!
7//! # Warning
8//!
9//! This is experimental cryptographic software, unless you're a cat with
10//! a megaphone on top of a giant Moogle I would exercise caution.
11//!
12//! - The protocol does not have a formal proof of security.
13//! - This library has not undergone any form of audit.
14//!
15//! # Design
16//!
17//! The main design principle of Cait-Sith is offloading as much work
18//! to a key-independent preprocessing phase as possible.
19//! The advantage of this approach is that this preprocessing phase can be conducted
20//! in advance, before a signature is needed, and the results of this phase
21//! can even be peformed before the key that you need to sign with is decided.
22//!
23//! One potential scenario where this is useful is when running a threshold
24//! custody service over many keys, where these preprocessing results
25//! can be performed, and then used on demand regardless of which keys
26//! end up being used more often.
27//!
28//! A detailed specification is available [in this repo](./docs),
29//! but we'll also give a bit of detail here.
30//!
31//! The core of Cait-Sith's design involves a *committed* Beaver triple.
32//! These are of the form:
33//! ```ignore
34//! ([a], [b], [c]), (A = a * G, B = b * G, C = c * G)
35//! ```
36//! where `a, b, c` are scalars such that `a * b = c`, and are
37//! secret shared among several participants, so that no one knows their actual value.
38//! Furthermore, unlike standard Beaver triples, we also have a public commitment
39//! to the these secret values, which helps the online protocol.
40//!
41//! The flow of the protocol is first that the parties need a way to generate triples:
42//!
43//! - A setup protocol is run once, allowing parties to efficiently generate triples.
44//! - The parties can now generate an arbitrary number triples through a distributed protocol.
45//!
46//! Then, the parties need to generate a key pair so that they can sign messages:
47//!
48//! - The parties run a distributed key generation protocol to setup a new key pair,
49//! which can be used for many signatures.
50//!
51//! When the parties want to sign using a given key:
52//!
53//! - Using their shares of a private key, the parties can create a *presignature*,
54//! before knowing the message to sign.
55//! - Once they know this message, they can use the presignature to create a complete signature.
56//!
57//! It's important that presignatures and triples are **never** reused.
58//!
59//! ## API Design
60//!
61//! Internally, the API tries to be as simple as possible abstracting away
62//! as many details as possible into a simple interface.
63//!
64//! This interface just has two methods:
65//! ```ignore
66//! pub trait Protocol {
67//! type Output;
68//!
69//! fn poke(&mut self) -> Result<Action<Self::Output>, ProtocolError>;
70//! fn message(&mut self, from: Participant, data: MessageData);
71//! }
72//! ```
73//! Given an instance of this trait, which represents a single party
74//! participating in a protocol, you can do two things:
75//! - You can provide a new message received from some other party.
76//! - You can "poke" the protocol to see if it has some kind of action it wants you to perform, or if an error happened.
77//!
78//! This action is either:
79//! - The protocol telling you it has finished, with a return value of type `Output`.
80//! - The protocol asking you to send a message to all other parties.
81//! - The protocol asking you to *privately* send a message to one party.
82//! - The protocol informing you that no more progress can be made until it receives new messages.
83//!
84//! In particular, details about rounds and message serialization are abstracted
85//! away, and all performed internally.
86//! In fact, the protocols aren't designed around "rounds", and can even have parallel
87//! threads of execution internally for some of the more complicated ones.
88//! # Generic Curves
89//!
90//! The library has support for generic curves and hashes.
91//!
92//! The support for generic curves is done through a custom `CSCurve` trait,
93//! which can be easily implemented for any curve from the
94//! RustCrypto [elliptic-curves](https://github.com/RustCrypto/elliptic-curves)
95//! suite of libraries.
96//!
97//! This crate also provides implementations of some existing curves behind features,
98//! as per the following table:
99//!
100//! | Curve | Feature |
101//! |-------|---------|
102//! |Secp256k1|`k256`|
103//!
104//! For supporting any message hash, the API requires the user to supply
105//! the hash of a message when signing as a scalar directly.
106//!
107//! # Shortcomings
108//!
109//! The protocol and its implementation do have a few known disadvantages at the moment:
110//!
111//! - The protocol does require generating triples in advance, but these can be generated without knowledge of the private key.
112//! - The protocol does not attempt to provide identifiable aborts.
113//!
114//! We also don't really intend to add identifiable aborts to Cait-Sith itself.
115//! While these can be desirable in certain situations, we aren't satisfied
116//! with the way the property of identifiable aborts is modeled currently,
117//! and are working on improvements to this model.
118mod compat;
119mod constants;
120mod crypto;
121mod keyshare;
122mod math;
123mod participants;
124mod presign;
125mod proofs;
126pub mod protocol;
127mod serde;
128mod sign;
129#[cfg(test)]
130mod test;
131pub mod triples;
132
133pub use compat::CSCurve;
134pub use keyshare::{keygen, refresh, reshare, KeygenOutput};
135pub use presign::{presign, PresignArguments, PresignOutput};
136pub use sign::{sign, FullSignature};