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
//! Pluggable transaction signing for Canton's interactive submission.
//!
//! Interactive submission splits a command in two: the participant *prepares* a
//! transaction and returns its hash, the party's key signs that hash, and the
//! signature comes back with an *execute* call. The participant never holds the
//! key — which is the point, and which is why the signing step has to be
//! somebody else's.
//!
//! [`Signer`] is that somebody. It is object-safe and its `sign` is async, so a
//! hardware module or a cloud KMS fits behind it without this crate knowing
//! anything about them:
//!
//! ```rust,ignore
//! let signer: Arc<dyn Signer> = Arc::new(my_kms_signer);
//! let prepared = client.prepare_submission(prepare).await?;
//! let executed = client.execute_submission(prepared.sign_with(&*signer).await?).await?;
//! ```
//!
//! The in-memory implementation, [`Ed25519Key`], is behind the default
//! `ed25519` feature. Turn it off (`default-features = false`) to take only the
//! trait.
//!
//! # A key is not yet an identity
//!
//! Canton addresses a key by a **fingerprint** it computes itself, and a
//! signature carries that fingerprint in `signed_by`. It is not derivable from
//! the key material here; a caller learns it from
//! `GenerateExternalPartyTopology`, which also yields the party id built from
//! it. So [`Ed25519Key`] holds key material and cannot sign for the ledger:
//! [`Ed25519Key::into_signer`] takes the fingerprint and returns something that
//! can. That ordering is the real one — you cannot sign as a party before the
//! participant has told you which party you are.
//!
//! # Security
//!
//! [`Ed25519Key`] holds a private key in process memory and is meant for
//! development, tests, and deployments where that is an accepted risk. It zeroes
//! nothing on drop and offers no protection against a process that can read its
//! own memory. Production keys belong in an HSM or KMS behind [`Signer`].
use fmt;
use Future;
use Pin;
use Result;
pub use ;
pub use ;
/// Something that can sign a prepared transaction's hash on a party's behalf.
///
/// Object-safe, so it is used as `Arc<dyn Signer>` — the same shape as
/// `canton_core::TokenSource`, and for the same reason: the SDK holds one
/// without knowing which implementation it is.
///
/// `sign` is async because the interesting implementations are a network call
/// away. The in-memory one simply returns a ready future.