essential_sign/contract.rs
1//! Signing, recovery and verification for contracts.
2//!
3//! Throughout the `essential` crates, contracts are represented as
4//! `Vec<Predicate>`. If we were to sign the `Vec<Predicate>` directly, the order of
5//! the predicates would need to be known in order to recover the signature. To
6//! avoid this unnecessary requirement we instead sign over [the content address
7//! of the contract][essential_hash::contract_addr].
8//!
9//! A [`contract::sign`][sign] shorthand function is provided to account for this
10//! special case.
11
12use essential_types::contract::{self, Contract};
13use secp256k1::{PublicKey, SecretKey};
14
15/// Sign over an contract.
16///
17/// This first determines the content address of the contract and signs the
18/// content address to produce the signature.
19///
20/// If the content address of the contract is already known, consider signing
21/// the content address directly with [`sign_hash`][crate::sign_hash] and then
22/// constructing the [`contract::SignedContract`] from its fields.
23pub fn sign(contract: Contract, sk: &SecretKey) -> contract::SignedContract {
24 let ca = essential_hash::content_addr(&contract);
25 let signature = crate::sign_hash(ca.0, sk);
26 contract::SignedContract {
27 contract,
28 signature,
29 }
30}
31
32/// Verifies the signature against the content address of the contract.
33pub fn verify(signed: &contract::SignedContract) -> Result<(), secp256k1::Error> {
34 let ca = essential_hash::content_addr(&signed.contract);
35 crate::verify_hash(ca.0, &signed.signature)
36}
37
38/// Recovers the public key with which the given contract was signed.
39///
40/// This first determines the content address of the contract and recovers
41/// over the content address.
42///
43/// If the content address of the contract is already known, consider recovering the
44/// content address directly.
45pub fn recover(signed: &contract::SignedContract) -> Result<PublicKey, secp256k1::Error> {
46 let ca = essential_hash::content_addr(&signed.contract);
47 crate::recover_hash(ca.0, &signed.signature)
48}