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

pub use keygen::{keygen, KeygenOutput};
pub use presign::{presign, PresignArguments, PresignOutput};
pub use sign::{sign, FullSignature};