pub trait Signer<SK: SignaturePrivateKey<SK_LEN>, const SK_LEN: usize, const SIG_LEN: usize>: Sized {
// Required methods
fn sign(
sk: &SK,
msg: &[u8],
ctx: Option<&[u8]>,
) -> Result<[u8; SIG_LEN], SignatureError>;
fn sign_out(
sk: &SK,
msg: &[u8],
ctx: Option<&[u8]>,
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>;
fn sign_init(sk: &SK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>;
fn sign_update(&mut self, msg_chunk: &[u8]);
fn sign_final(self) -> Result<[u8; SIG_LEN], SignatureError>;
fn sign_final_out(
self,
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>;
}Expand description
A digital signature algorithm is defined as a set of three operations: key generation, signing, and verification.
This trait represents the operations performed by the holder of the signing private key:
which include signing and key generation. Verification operations are performed by the corresponding
SignatureVerifier trait.
There are several reasons for this split: first is architectural; some complex algorithms may
benefit from having the signature generation and verification implementations split into separate modules.
Second is for compliance: sometimes a policy soft-deprecates an algorithm so that new signatures
can no longer be created, but existing signatures can still be verified. Splitting the traits
makes this policy easier to enforce.
This high-level trait defines the operations over a generic signature algorithm that is assumed to source all its randomness from bouncycastle’s default os-backed RNG. The underlying signature primitives will expose APIs that allow for specifying a specific RNG or deterministic seed values.
The arrays used to encode public keys, private keys, and signature values are statically-sized because this allows us to safely remove runtime checks for array lengths, which overall reduces the fallibility of the library. This design choice could make this trait complicated to apply to a signature algorithm that do not have fixed sizes for the encodings of these objects.
Required Methods§
Sourcefn sign(
sk: &SK,
msg: &[u8],
ctx: Option<&[u8]>,
) -> Result<[u8; SIG_LEN], SignatureError>
fn sign( sk: &SK, msg: &[u8], ctx: Option<&[u8]>, ) -> Result<[u8; SIG_LEN], SignatureError>
Produce a signature for the provided message and context.
Both the msg and ctx accept zero-length byte arrays.
A note about the ctx context parameter:
This is a newer addition to cryptographic signature primitives. It allows for binding the
signature to some external property of the application so that a signature will fail to validate
if removed from its intended context.
This is particularly useful at preventing content confusion attacks between data formats that
have very similar data structures, for example S/MIME emails, signed PDFs, and signed executables
that all use the Cryptographic Message Syntax (CMS) data format, or multiple data objects that
all use the JWS data format.
To be properly effective, the ctx value must not be under the control of the attacker, which generally
means that it needs to be a value that is never transmitted over the wire, but rather is something
known to the application by context.
For example, “email” vs “pdf” would be a good choice since the application should know what it is
attempting to sign or verify.
The ctx param can also be used to bind the signed content to a transaction ID or a username,
but care should be taken to ensure that an attacker attempting a
content confusion attack not also cause the signed / verifier to use an incorrect transaction ID or username.
Not all signature primitives will support a context value, so you may need to consult the documentation for the underlying primitive for how it handles a ctx in that case, for example, it might throw an error, ignore the provided ctx value, or append the ctx to the msg in a non-standard way.
Sourcefn sign_out(
sk: &SK,
msg: &[u8],
ctx: Option<&[u8]>,
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>
fn sign_out( sk: &SK, msg: &[u8], ctx: Option<&[u8]>, output: &mut [u8; SIG_LEN], ) -> Result<usize, SignatureError>
Returns the number of bytes written to the output buffer. Can be called with an oversized buffer. The entire output buffer is zeroized before the signature is written.
Sourcefn sign_init(sk: &SK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>
fn sign_init(sk: &SK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>
Initialize a signer for streaming mode with the provided private key.
Sourcefn sign_update(&mut self, msg_chunk: &[u8])
fn sign_update(&mut self, msg_chunk: &[u8])
Update the signer with the next chunk of data. This can be called multiple times.
Sourcefn sign_final(self) -> Result<[u8; SIG_LEN], SignatureError>
fn sign_final(self) -> Result<[u8; SIG_LEN], SignatureError>
Complete the signing operation. Consumes self.
Sourcefn sign_final_out(
self,
output: &mut [u8; SIG_LEN],
) -> Result<usize, SignatureError>
fn sign_final_out( self, output: &mut [u8; SIG_LEN], ) -> Result<usize, SignatureError>
Returns the number of bytes written to the output buffer. Can be called with an oversized buffer. The entire output buffer is zeroized before the signature is written.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.