envelope.rs
Overview
This file defines the Envelope structure and the BLSSignedEnvelope trait to represent and manage data envelopes that are cryptographically signed using BLS (Boneh–Lynn–Shacham) signature schemes. These envelopes encapsulate arbitrary data (TData) alongside aggregated BLS signatures and track which signers have contributed to the signature aggregation. The file enables creation, signature aggregation, signature verification, and serialization/deserialization of such envelopes, facilitating secure multi-signer cryptographic data handling.
Traits and Structs
BLSSignedEnvelope Trait
The BLSSignedEnvelope trait defines the required interface for any envelope type that supports BLS signatures. It is generic over associated types for the BLS signature scheme, the envelope's data, and the signer index.
Associated Types
BLS: The BLS signature scheme type implementing theBLSSignatureSchemetrait.Data: The type of data contained within the envelope.SignerIndex: The type representing the identity or index of a signer.
Required Methods
create<T: Into<Self::Data>>(aggregated_signature: <Self::BLS as BLSSignatureScheme>::Signature, signature_occurrences: HashMap<Self::SignerIndex, u16>, data: T) -> SelfCreates a new envelope instance with initial aggregated signature, a mapping of signature occurrences per signer, and the data payload.
add_signature(&mut self, signer_index: &Self::SignerIndex, secret: &<Self::BLS as BLSSignatureScheme>::Secret) -> anyhow::Result<()>Adds a signature from a new signer by signing the envelope's data with the signer's secret key and aggregating it into the envelope's existing signature.
clone_signature_occurrences(&self) -> HashMap<Self::SignerIndex, u16>Returns a clone of the internal map that tracks how many times each signer has signed the envelope.
verify_signatures(&self, signers: &HashMap<Self::SignerIndex, <Self::BLS as BLSSignatureScheme>::PubKey>) -> anyhow::Result<bool>Verifies the aggregated signature against the public keys of the signers, confirming the authenticity and integrity of the envelope's data.
aggregated_signature(&self) -> &<Self::BLS as BLSSignatureScheme>::SignatureReturns a reference to the aggregated BLS signature.
data(&self) -> &Self::DataReturns a reference to the data contained within the envelope.
has_signer_index(&self, index: Self::SignerIndex) -> boolChecks if a particular signer has contributed a signature.
signatures_count(&self) -> usizeReturns the number of distinct signers who have signed the envelope.
signers(&self) -> impl Iterator<Item = &Self::SignerIndex>Returns an iterator over the signer indices who have signed the envelope.
Envelope<BLS, TData> Struct
A concrete implementation of the BLSSignedEnvelope trait that holds an aggregated BLS signature, a map of signature occurrences keyed by signer indices, and the data payload.
Type Parameters
BLS: The BLS signature scheme implementing theBLSSignatureSchemetrait.TData: The data type contained in the envelope.
Fields
aggregated_signature: BLS::SignatureThe aggregated BLS signature representing the combined signatures of all signers.
signature_occurrences: HashMap<SignerIndex, u16>Records the number of signatures each signer has contributed.
data: TDataThe actual data payload contained within the envelope.
Trait Implementations
Implements
BLSSignedEnvelopewith functionality to create envelopes, add signatures, verify signatures, access data, and enumerate signers.Implements
Displayto provide a human-readable string representation showing the data and signature occurrences.Implements Debug for debug formatting of the envelope's internal state.
Implements Serialize and Deserialize to support serialization and deserialization of the envelope, including sorting the signature occurrences for consistent serialization output.
Method Details
create
Creates a new envelope instance.
let envelope = Envelope::<MyBLS, MyData>::create(
initial_aggregated_signature,
initial_signature_occurrences,
my_data,
);
add_signature
Adds a new signature from a signer, updating the aggregated signature and signature occurrences map.
envelope.add_signature(&signer_index, &signer_secret)?;
Signs the envelope data using the provided secret key.
Merges the new signature into the aggregated signature.
Updates
signature_occurrencesby incrementing the count for thesigner_index.
verify_signatures
Verifies the aggregated signature against provided public keys of signers.
let is_valid = envelope.verify_signatures(&signers_pubkey_map)?;
Collects public keys and their signature counts from
signature_occurrences.Performs BLS verification of the aggregated signature.
Returns
trueif verification succeeds,falseotherwise.
clone_signature_occurrences
Returns a cloned map of signers and their signature counts.
has_signer_index
Checks if a signer index has signed the envelope.
if envelope.has_signer_index(signer_index) {
// signer has signed
}
signatures_count
Returns the number of unique signers.
signers
Returns an iterator over the signer indices who have signed.
aggregated_signature and data
Accessors for the aggregated signature and envelope data.
EnvelopeSerDe<TSignature, TData> Struct
A helper structure used internally for serialization and deserialization of the Envelope. It stores the aggregated signature, a sorted vector of signature occurrences (to ensure consistent serialization order), and the data.
Implementation Details and Algorithms
Signature Aggregation: When adding a new signature via
add_signature, the envelope signs its internal data using the signer's secret key, then merges the new signature into the existing aggregated signature using BLS signature merging (BLS::merge).Signature Verification: The
verify_signaturesmethod constructs a vector of(PubKey, occurrence)pairs from known signers and their signature counts. This vector is passed toBLS::verifyalong with the aggregated signature and data. This method validates that the aggregated signature correctly represents all individual signatures.Serialization Consistency: To ensure consistent serialized output,
signature_occurrencesare converted to a vector and sorted by signer index before serialization.Signature Occurrence Tracking: The envelope tracks how many times each signer has signed the data, enabling detection of repeated signatures from the same signer.
Interaction With Other Parts of the System
BLS Signature Scheme (
BLSSignatureScheme): The envelope depends on the BLS signature scheme abstraction, which provides methods for signing, merging signatures, and verifying aggregated signatures.SignerIndex (
node::SignerIndex): Used as keys to identify signers uniquely within the signature occurrences map.Cryptographic Secrets and Public Keys: The envelope uses secret keys (
BLS::Secret) to add signatures and public keys (BLS::PubKey) to verify signatures.Serialization/Deserialization: Interfaces with
serdefor converting envelopes to/from serialized formats, enabling network transmission or storage.
Visual Diagram
classDiagram
class BLSSignedEnvelope {
<<trait>>
+create()
+add_signature()
+clone_signature_occurrences()
+verify_signatures()
+aggregated_signature()
+data()
+has_signer_index()
+signatures_count()
+signers()
}
class Envelope {
-aggregated_signature
-signature_occurrences
-data
+create()
+add_signature()
+clone_signature_occurrences()
+verify_signatures()
+aggregated_signature()
+data()
+has_signer_index()
+signatures_count()
+signers()
+serialize()
+deserialize()
+fmt()
+debug_fmt()
}
BLSSignedEnvelope <|.. Envelope