Skip to main content

bouncycastle_core_interface/
traits.rs

1//! Provides simplified abstracted APIs over classes of cryptigraphic primitives, such as Hash, KDF, etc.
2
3use std::fmt::{Debug, Display};
4use crate::errors::{HashError, KDFError, MACError, RNGError, SignatureError};
5pub use crate::key_material::KeyMaterial;
6
7// Imports needed for docs
8#[allow(unused_imports)]
9use crate::key_material::KeyMaterialSized;
10#[allow(unused_imports)]
11use crate::key_material::KeyType;
12// end of imports needed for docs
13
14pub trait Algorithm {
15    const ALG_NAME: &'static str;
16    const MAX_SECURITY_STRENGTH: SecurityStrength;
17}
18
19pub trait Hash : Default {
20    /// The size of the internal block in bits -- needed by functions such as HMAC to compute security parameters.
21    fn block_bitlen(&self) -> usize;
22
23    /// The size of the output in bytes.
24    fn output_len(&self) -> usize;
25
26    /// A static one-shot API that hashes the provided data.
27    /// `data` can be of any length, including zero bytes.
28    fn hash(self, data: &[u8]) -> Vec<u8>;
29
30    /// A static one-shot API that hashes the provided data into the provided output slice.
31    /// `data` can be of any length, including zero bytes.
32    /// The return value is the number of bytes written.
33    fn hash_out(self, data: &[u8], output: &mut [u8]) -> usize;
34
35    /// Provide a chunk of data to be absorbed into the hashes.
36    /// `data` can be of any length, including zero bytes.
37    /// do_update() is intended to be used as part of a streaming interface, and so may by called multiple times.
38    // fn do_update(&mut self, data: &[u8]) -> Result<(), HashError>;
39    fn do_update(&mut self, data: &[u8]);
40
41    /// Finish absorbing input and produce the hashes output.
42    /// Consumes self, so this must be the final call to this object.
43    // fn do_final(self) -> Result<Vec<u8>, HashError>;
44    fn do_final(self) -> Vec<u8>;
45
46    /// Finish absorbing input and produce the hashes output.
47    /// Consumes self, so this must be the final call to this object.
48    ///
49    /// If the provided buffer is smaller than the hash's output length, the output will be truncated.
50    /// If the provided buffor is larger than the hash's output length, the output  will be placed in
51    /// the first [Hash::output_len] bytes.
52    ///
53    /// The return value is the number of bytes written.
54    fn do_final_out(self, output: &mut [u8]) -> usize;
55
56    /// The same as [Hash::do_final], but allows for supplying a partial byte as the last input.
57    /// Assumes that the input is in the least significant bits (big endian).
58    fn do_final_partial_bits(
59        self,
60        partial_byte: u8,
61        num_partial_bits: usize,
62    ) -> Result<Vec<u8>, HashError>;
63
64    /// The same as [Hash::do_final_out], but allows for supplying a partial byte as the last input.
65    /// Assumes that the input is in the least significant bits (big endian).
66    /// will be placed in the first [Hash::output_len] bytes.
67    /// The return value is the number of bytes written.
68    fn do_final_partial_bits_out(
69        self,
70        partial_byte: u8,
71        num_partial_bits: usize,
72        output: &mut [u8],
73    ) -> Result<usize, HashError>;
74
75    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
76    fn max_security_strength(&self) -> SecurityStrength;
77}
78
79pub trait HashAlgParams: Algorithm {
80    const OUTPUT_LEN: usize;
81    const BLOCK_LEN: usize;
82}
83
84/// A Key Derivation Function (KDF) is a function that takes in one or more input key and some unstructured
85/// additional input, and uses them to produces a derived key.
86pub trait KDF : Default {
87    /// Implementations of this function are capable of deriving an output key from an input key,
88    /// assuming that they have been properly initialized.
89    ///
90    /// # Entropy Conversion rules
91    /// Implementations SHOULD act on a KeyMaterial of any [KeyType] and will generally
92    /// return a KeyMaterial of the same type
93    ///
94    /// ex.:
95    ///
96    ///   * [KeyType::BytesLowEntropy] -> [KeyType::BytesLowEntropy])
97    ///   * [KeyType::BytesFullEntropy] -> [KeyType::BytesFullEntropy])
98    ///   * [KeyType::SymmetricCipherKey] -> [KeyType::SymmetricCipherKey])
99    ///
100    /// If provided with an input key, even if it is [KeyType::BytesFullEntropy], but that
101    /// contains less key material than the internal block size of the KDF, then the KDF
102    /// will not be considered properly seeded, and the output [KeyMaterialSized] will be set to
103    /// [KeyType::BytesLowEntropy] -- for example, seeding SHA3-256 with a [KeyMaterialSized] containing
104    /// only 128 bits of key material.
105    ///
106    /// An implement can, and in most cases SHOULD, return a [HashError] if provided
107    /// with a [KeyMaterialSized] of type [KeyType::Zeroized].
108    ///
109    /// # Additional Input
110    /// The `additional_input` parameter is used in deriving the key, but is not credited with any entropy,
111    /// and therefore does not affect the type of the output [KeyMaterialSized].
112    /// This corresponds directly to `FixedInfo` as defined in NIST SP 800-56C.
113    /// The `additional_input` parameter can be empty by passing in `&[0u8; 0]`.
114    ///
115    /// Output length: this function will create a KeyMaterial populated with the default output length
116    /// of the underlying hash primitive.
117    fn derive_key(
118        self,
119        key: &impl KeyMaterial,
120        additional_input: &[u8],
121    ) -> Result<Box<dyn KeyMaterial>, KDFError>;
122
123    /// Same as [KDF::derive_key], but fills the provided output [KeyMaterialSized].
124    ///
125    /// Output length: this function will behave differently depending on the underlying hash primitive;
126    /// some, such as SHA2 or SHA3 will produce a fixed-length output, while others, such as SHAKE or HKDF,
127    /// will fill the provided KeyMaterial to capacity and require you to truncate it afterwards
128    /// using [KeyMaterial::truncate].
129    fn derive_key_out(
130        self,
131        key: &impl KeyMaterial,
132        additional_input: &[u8],
133        output_key: &mut impl KeyMaterial,
134    ) -> Result<usize, KDFError>;
135
136    /// Meant to be used for hybrid key establishment schemes or other spit-key scenarios where multiple
137    /// keys need to be combined into a single key of the same length.
138    ///
139    /// This function can also be used to mix a KeyMaterial of low entropy with one of full entropy to
140    /// produce a new full entropy key. For the purposes of determining whether enough input key material
141    /// was provided, the lengths of all full-entropy input keys are added together.
142    ///
143    /// Implementations that are not safe to be used as a split-key PRF MAY still implement this function
144    /// and return a result, but SHOULD set the entropy level of the returned key appropriately; for example
145    /// a KDF that is only full-entropy when keyed in the first input SHOULD return a full entropy key
146    /// only if the first input is full entropy.
147    ///
148    /// Implementations can, and in most cases SHOULD, return a [KeyMaterialSized] of the same type as the
149    /// strongest key, and SHOULD throw a [HashError] if all input keys are zeroized.
150    /// For example output a [KeyType::BytesFullEntropy] key whenever any one of
151    /// the input keys is a [KeyType::BytesFullEntropy] key.
152    /// As another example, combining a [KeyType::BytesLowEntropy] key with a [KeyType::MACKey] key
153    /// should return a [KeyType::MACKey].
154    ///
155    /// Output length: this function will create a KeyMaterial populated with the default output length
156    /// of the underlying hash primitive.
157    fn derive_key_from_multiple(
158        self,
159        keys: &[&impl KeyMaterial],
160        additional_input: &[u8],
161    ) -> Result<Box<dyn KeyMaterial>, KDFError>;
162
163    /// Same as [KDF::derive_key], but fills the provided output [KeyMaterialSized].
164    ///
165    /// Output length: this function will behave differently depending on the underlying hash primitive;
166    /// some, such as SHA2 or SHA3 will produce a fixed-length output, while others, such as SHAKE or HKDF,
167    /// will fill the provided KeyMaterial to capacity and require you to truncate it afterwards
168    /// by using [KeyMaterial::truncate].
169    fn derive_key_from_multiple_out(
170        self,
171        keys: &[&impl KeyMaterial],
172        additional_input: &[u8],
173        output_key: &mut impl KeyMaterial,
174    ) -> Result<usize, KDFError>;
175
176    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
177    fn max_security_strength(&self) -> SecurityStrength;
178}
179
180/// A Message Authentication Code algorithm is a keyed hash function that behaves somewhat like a symmetric signature function.
181/// A MAC algorithm takes in a key and some data, and produces a MAC (message authentication code) that
182/// can be used to verify the integrity of data.
183///
184/// This trait provides one-shot functions [MAC::mac], [MAC::mac_out], and [MAC::verify].
185/// It also provides streaming functions [MAC::do_update], [MAC::do_final], [MAC::do_final_out],
186/// and [MAC::do_verify_final].
187/// The workflow is that a MAC object is initialized with a key with [MAC::new] -- or [MAC::new_allow_weak_key] if you
188/// need to disable the library's safety mechanism to prevent the use of weak keys -- then data is
189/// processed into one or more calls to [MAC::do_update],
190/// after that the object can either create a MAC with [MAC::do_final] or [MAC::do_final_out] (which are final functions, and so consume the object),
191/// or the object can be used to verify a MAC.
192///
193/// For varifying an existing MAC, it is functionally equivalent to use the provided [MAC::verify] and [MAC::do_verify_final]
194/// function or to compute a new MAC and compare it to the existing MAC, however the provided verification functions
195/// use constant-time comparison to avoid cryptographic timing attacks whereby an attacker could learn
196/// the bytes of the MAC value under some conditions. Therefore, it is highly recommended to use the provided verification functions.
197///
198/// Note that the MAC key is not represented in this trait because it is provided to the MAC algorithm
199/// as part of its new functions.
200///
201/// MACs do not implement Default because they do not have a sensible no-args constructor.
202pub trait MAC: Sized {
203
204    /// Create a new MAC instance with the given key.
205    ///
206    /// This is a common constructor whether creating or verifying a MAC value.
207    ///
208    /// Key / Salt is optional, which is indicated by providing an uninitialized KeyMaterial object of length zero,
209    /// the capacity is irrelevant, so KeyMateriol256::new() or KeyMaterial_internal::<0>::new() would both count as an absent salt.
210    ///
211    /// # Note about the security strength of the provided key:
212    /// If you initialize the MAC with a key that is tagged at a lower [SecurityStrength] than the
213    /// underlying hash function then [MAC::new] will fail with the following error:
214    /// ```text
215    /// MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC")
216    /// ```
217    /// There are situations in which it is completely reasonable and secure to provide low-entropy
218    /// (and sometimes all-zero) keys / salts; for these cases we have provided [MAC::new_allow_weak_key].
219    fn new(key: &impl KeyMaterial) -> Result<Self, MACError>;
220
221    /// Create a new HMAC instance with the given key.
222    ///
223    /// This constructor completely ignores the [SecurityStrength] tag on the input key and will "just work".
224    /// This should be used if you really do need to use a weak key, such as an all-zero salt,
225    /// but use of this constructor is discouraged and you should really be asking yourself why you need it;
226    /// in most cases it indicates that your key is not long enough to support the security level of this
227    /// HMAC instance, or the key was derived using algorithms at a lower security level, etc.
228    fn new_allow_weak_key(key: &impl KeyMaterial) -> Result<Self, MACError>;
229
230    /// The size of the output in bytes.
231    fn output_len(&self) -> usize;
232
233    /// One-shot API that computes a MAC for the provided data.
234    /// `data` can be of any length, including zero bytes.
235    ///
236    /// Note about the security strength of the provided key:
237    /// If the provided key is tagged at a lower [SecurityStrength] than the instantiated MAC algorithm,
238    /// this will fail with an error:
239    /// ```text
240    /// MACError::KeyMaterialError(KeyMaterialError::SecurityStrength("HMAC::init(): provided key has a lower security strength than the instantiated HMAC")
241    /// ```
242    fn mac(self, data: &[u8]) -> Vec<u8>;
243
244    /// One-shot API that computes a MAC for the provided data and writes it into the provided output slice.
245    /// `data` can be of any length, including zero bytes.
246    ///
247    /// Depending on the underlying MAC implementation, NIST may require that the library enforce
248    /// a minimum length on the mac output value. See documentation for the underlying implementation
249    /// to see conditions under which it throws [MACError::InvalidLength].
250    fn mac_out(self, data: &[u8],out: &mut [u8]) -> Result<usize, MACError>;
251
252    /// One-shot API that verifies a MAC for the provided data.
253    /// `data` can be of any length, including zero bytes.
254    ///
255    /// Internally, this will re-compute the MAC value and then compare it to the provided mac value
256    /// using constant-time comparison. It is highly encouraged to use this utility function instead of
257    /// comparing mac values for equality yourself.
258    ///
259    /// Returns a bool to indicate successful verification of the provided mac value.
260    /// The provided mac value must be an exact match, including length; for example a mac value
261    /// which has been truncated, or which contains extra bytes at the end is considered to not be a match
262    /// and will return false.
263    fn verify(self, data: &[u8], mac: &[u8]) -> bool;
264
265    /// Provide a chunk of data to be absorbed into the MAC.
266    /// `data` can be of any length, including zero bytes.
267    /// do_update() is intended to be used as part of a streaming interface, and so may by called multiple times.
268    fn do_update(&mut self, data: &[u8]);
269
270    fn do_final(self) -> Vec<u8>;
271
272    /// Depending on the underlying MAC implementation, NIST may require that the library enforce
273    /// a minimum length on the mac output value. See documentation for the underlying implementation
274    /// to see conditions under which it throws [MACError::InvalidLength].
275    fn do_final_out(self, out: &mut [u8]) -> Result<usize, MACError>;
276
277    /// Internally, this will re-compute the MAC value and then compare it to the provided mac value
278    /// using constant-time comparison. It is highly encouraged to use this utility function instead of
279    /// comparing mac values for equality yourself.
280    ///
281    /// Returns a bool to indicate successful verification of the provided mac value.
282    /// The provided mac value must be an exact match, including length; for example a mac value
283    /// which has been truncated, or which contains extra bytes at the end is considered to not be a match
284    /// and will return false.
285    fn do_verify_final(self, mac: &[u8]) -> bool;
286
287    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
288    fn max_security_strength(&self) -> SecurityStrength;
289}
290
291#[derive(Eq, PartialEq, PartialOrd, Clone, Debug)]
292pub enum SecurityStrength {
293    None,
294    _112bit,
295    _128bit,
296    _192bit,
297    _256bit,
298}
299
300impl SecurityStrength {
301    /// Rounds down to the closest supported security strength.
302    /// For example, 120-bits is rounded down to 112-bit.
303    pub fn from_bits(bits: usize) -> Self {
304        if bits < 112 {
305            Self::None
306        } else if bits < 128 {
307            Self::_112bit
308        } else if bits < 192 {
309            Self::_128bit
310        } else if bits < 256 {
311            Self::_192bit
312        } else {
313            Self::_256bit
314        }
315    }
316
317    pub fn from_bytes(bytes: usize) -> Self {
318        Self::from_bits(bytes * 8)
319    }
320
321    pub fn as_int(&self) -> u32 {
322        match self {
323            Self::None => 0,
324            Self::_112bit => 112,
325            Self::_128bit => 128,
326            Self::_192bit => 192,
327            Self::_256bit => 256,
328        }
329    }
330}
331
332/// An interface for random number generation.
333/// This interface is meant to be simpler and more ergonomic than the interfaces provided by the
334/// `rng` crate, but that one should
335/// be used by applications that intend to submit to FIPS certification as it more closely aligns with the
336/// requirements of SP 800-90A.
337/// Note: this interface produces bytes. If you want a [KeyMaterial], then use [KeyMaterialSized::from_rng].
338pub trait RNG : Default {
339    // TODO: add back once we figure out streaming interaction with entropy sources.
340    // fn add_seed_bytes(&mut self, additional_seed: &[u8]) -> Result<(), RNGError>;
341
342    fn add_seed_keymaterial(&mut self, additional_seed: impl KeyMaterial) -> Result<(), RNGError>;
343    fn next_int(&mut self) -> Result<u32, RNGError>;
344
345    /// Returns the number of requested bytes.
346    fn next_bytes(&mut self, len: usize) -> Result<Vec<u8>, RNGError>;
347
348    /// Returns the number of bytes written.
349    fn next_bytes_out(&mut self, out: &mut [u8]) -> Result<usize, RNGError>;
350
351    fn fill_keymaterial_out(&mut self, out: &mut impl KeyMaterial) -> Result<usize, RNGError>;
352
353    /// Returns the Security Strength of this RNG.
354    fn security_strength(&self) -> SecurityStrength;
355}
356
357/// A trait that forces an object to implement a zeroizing Drop() as well as Debug and Display that
358/// will not log the sensitive contents, even in error or crash-dump scenarios.
359#[allow(drop_bounds)] // Since rust auto-implements Drop, there's a lint that explicitly bounding on Drop is useless.
360                      // I disagree because I want to force things that are secrets to manually implement Drop that zeroizes the data.
361                      // So I'm turning off this lint.
362pub trait Secret : Drop + Debug + Display {}
363
364/// Pre-Hashed Signature is an extension to [Signature] that adds functionality specific to signature
365/// primatives that can operate on a pre-hashed message instead of the full message.
366pub trait PHSignature<PK: SignaturePublicKey, SK: SignaturePrivateKey, const PH_LEN: usize>:
367    Signature<PK, SK>{
368    /// Produce a signature for the provided pre-hashed message and context.
369    ///
370    /// `ctx` accepts a zero-length byte array.
371    ///
372    /// A note about the `ctx` context parameter:
373    /// This is a newer addition to cryptographic signature primitives. It allows for binding the
374    /// signature to some external property of the application so that a signature will fail to validate
375    /// if removed from its intended context.
376    /// This is particularly useful at preventing content confusion attacks between data formats that
377    /// have very similar data structures, for example S/MIME emails, signed PDFs, and signed executables
378    /// that all use the Cryptographic Message Syntax (CMS) data format, or multiple data objects that
379    /// all use the JWS data format.
380    /// To be properly effective, the ctx value must not be under the control of the attacker, which generally
381    /// means that it needs to be a value that is never transmitted over the wire, but rather is something
382    /// known to the application by context.
383    /// For example, "email" vs "pdf" would be a good choice since the application should know what it is
384    /// attempting to sign or verify.
385    /// The `ctx` param can also be used to bind the signed content to a transaction ID or a username,
386    /// but care should be taken to ensure that an attacker attempting a
387    /// content confusion attack not also cause the signed / verifier to use an incorrect transaction ID or username.
388    ///
389    /// Not all signature primitives will support a context value, so you may need to consult the
390    /// documentation for the underlying primitive for how it handles a ctx in that case, for example, it
391    /// might throw an error, ignore the provided ctx value, or append the ctx to the msg in a non-standard way.
392    fn sign_ph(sk: &SK, ph: &[u8; PH_LEN], ctx: Option<&[u8]>) -> Result<Vec<u8>, SignatureError>;
393    /// Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
394    fn sign_ph_out(sk: &SK, ph: &[u8; PH_LEN], ctx: Option<&[u8]>, output: &mut [u8]) -> Result<usize, SignatureError>;
395    /// On success, returns Ok(())
396    /// On failure, returns Err([SignatureError::SignatureVerificationFailed]); may also return other types of [SignatureError] as appropriate (such as for invalid-length inputs).
397    fn verify_ph(pk: &PK, ph: &[u8; PH_LEN], ctx: Option<&[u8]>, sig: &[u8]) -> Result<(), SignatureError>;
398}
399
400/// A digital signature algorithm is defined as a set of three operations:
401/// key generation, signing, and verification.
402///
403/// To avoid the use of dyn, this trait does not include key generation; you'll have to consult the
404/// documentation for the underlying signature primitive for how to generate a key pair.
405///
406/// This high-level trait defines the operations over a generic signature algorithm that is assumed
407/// to source all its randomness from bouncycastle's default os-backed RNG.
408/// The underlying signature primitives will expose APIs that allow for specifying a specific RNG
409/// or deterministic seed values.
410// Note to future maintainers: this could have had a SIG_LEN a param and then done [u8; SIG_LEN] throughout and removed a whole bunch of Results,
411// but in general there exist signature algs with non-fixed-length signature values.
412pub trait Signature<PK: SignaturePublicKey, SK: SignaturePrivateKey>: Sized {
413    /// Generate a keypair.
414    /// Error condition: Basically only on RNG failures
415    fn keygen() -> Result<(PK, SK), SignatureError>;
416
417    /// Produce a signature for the provided message and context.
418    /// Both the `msg` and `ctx` accept zero-length byte arrays.
419    ///
420    /// A note about the `ctx` context parameter:
421    /// This is a newer addition to cryptographic signature primitives. It allows for binding the
422    /// signature to some external property of the application so that a signature will fail to validate
423    /// if removed from its intended context.
424    /// This is particularly useful at preventing content confusion attacks between data formats that
425    /// have very similar data structures, for example S/MIME emails, signed PDFs, and signed executables
426    /// that all use the Cryptographic Message Syntax (CMS) data format, or multiple data objects that
427    /// all use the JWS data format.
428    /// To be properly effective, the ctx value must not be under the control of the attacker, which generally
429    /// means that it needs to be a value that is never transmitted over the wire, but rather is something
430    /// known to the application by context.
431    /// For example, "email" vs "pdf" would be a good choice since the application should know what it is
432    /// attempting to sign or verify.
433    /// The `ctx` param can also be used to bind the signed content to a transaction ID or a username,
434    /// but care should be taken to ensure that an attacker attempting a
435    /// content confusion attack not also cause the signed / verifier to use an incorrect transaction ID or username.
436    ///
437    /// Not all signature primitives will support a context value, so you may need to consult the
438    /// documentation for the underlying primitive for how it handles a ctx in that case, for example, it
439    /// might throw an error, ignore the provided ctx value, or append the ctx to the msg in a non-standard way.
440    fn sign(sk: &SK, msg: &[u8], ctx: Option<&[u8]>) -> Result<Vec<u8>, SignatureError>;
441
442    /// Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
443    fn sign_out(sk: &SK, msg: &[u8], ctx: Option<&[u8]>, output: &mut [u8]) -> Result<usize, SignatureError>;
444
445    /* streaming signing API */
446    /// Initialize a signer for streaming mode with the provided private key.
447    fn sign_init(sk: &SK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>;
448
449    fn sign_update(&mut self, msg_chunk: &[u8]);
450
451    /// Complete the signing operation. Consumes self.
452    fn sign_final(self) -> Result<Vec<u8>, SignatureError>;
453
454    /// Returns the number of bytes written to the output buffer. Can be called with an oversized buffer.
455    fn sign_final_out(self, output: &mut [u8]) -> Result<usize, SignatureError>;
456
457    /// On success, returns Ok(())
458    /// On failure, returns Err([SignatureError::SignatureVerificationFailed]); may also return other types of [SignatureError] as appropriate (such as for invalid-length inputs).
459    fn verify(pk: &PK, msg: &[u8], ctx: Option<&[u8]>, sig: &[u8]) -> Result<(), SignatureError>;
460
461    /* streaming verification API */
462    fn verify_init(pk: &PK, ctx: Option<&[u8]>) -> Result<Self, SignatureError>;
463
464    fn verify_update(&mut self, msg_chunk: &[u8]);
465
466    /// On success, returns Ok(())
467    /// On failure, returns Err([SignatureError::SignatureVerificationFailed]); may also return other types of [SignatureError] as appropriate (such as for invalid-length inputs).
468    fn verify_final(self, sig: &[u8]) -> Result<(), SignatureError>;
469}
470
471/// A public key for a signature algorithm, often denoted "pk".
472pub trait SignaturePublicKey : PartialEq + Eq + Clone + Debug + Display + Sized {
473    /// Write it out to bytes in its standard encoding.
474    fn encode(&self) -> Vec<u8>;
475
476    /// Write it out to bytes in its standard encoding.
477    fn encode_out(&self, out: &mut [u8]) -> Result<usize, SignatureError>;
478
479    /// Read it in from bytes in its standard encoding.
480    fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError>;
481}
482
483/// A private key for a signature algorithm, often denoted "sk" (for "secret key").
484pub trait SignaturePrivateKey: PartialEq + Eq + Clone + Debug + Display + Sized {
485    /// Write it out to bytes in its standard encoding.
486    fn encode(&self) -> Vec<u8>;
487
488    /// Write it out to bytes in its standard encoding.
489    fn encode_out(&self, out: &mut [u8]) -> Result<usize, SignatureError>;
490
491    /// Read it in from bytes in its standard encoding.
492    fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError>;
493}
494
495/// Extensible Output Functions (XOFs) are similar to hash functions, except that they can produce output of arbitrary length.
496/// The naming used for the functions of this trait are borrowed from the SHA3-style sponge constructions that split XOF operation
497/// into two phases: an absorb phase in which an arbitrary amount of input is provided to the XOF,
498/// and then a squeeze phase in which an arbitrary amount of output is extracted.
499/// Once squeezing begins, no more input can be absorbed.
500///
501/// XOFs are _similar to_ hash functions, but are not hash functions for one technical but important reason:
502/// since the amount of output to produce is not provided to the XOF in advance, it cannot be used to
503/// diversify the XOF output streams.
504/// In other words, the overlapping parts of their outputs will be the same!
505/// For example, consider two XOFs that absorb the same input data, one that is squeezed to produce 32 bytes,
506/// and the other to produce 1 kb; both outputs will be identical in their first 32 bytes.
507/// This could lead to loss of security in a number of ways, for example distinguishing attacks where
508/// it is sufficient for the attacker to know that two values came from the same input, even if the
509/// attacker cannot learn what that input was. This is attack is often sufficient, for example,
510/// to break anonymity-preserving technology.
511/// Applications that require the arbitrary-length output of an XOF, but also care about these
512/// distinguishing attacks should consider adding a cryptographic salt to diversify the inputs.
513pub trait XOF : Default {
514    /// A static one-shot API that digests the input data and produces `result_len` bytes of output.
515    fn hash_xof(self, data: &[u8], result_len: usize) -> Vec<u8>;
516
517    /// A static one-shot API that digests the input data and produces `result_len` bytes of output.
518    /// Fills the provided output slice.
519    fn hash_xof_out(self, data: &[u8], output: &mut [u8]) -> usize;
520
521    fn absorb(&mut self, data: &[u8]);
522
523    /// Switches to squeezing.
524    fn absorb_last_partial_byte(
525        &mut self,
526        partial_byte: u8,
527        num_partial_bits: usize,
528    ) -> Result<(), HashError>;
529
530    /// Can be called multiple times.
531    fn squeeze(&mut self, num_bytes: usize) -> Vec<u8>;
532
533    /// Can be called multiple times.
534    /// Fills the provided output slice.
535    fn squeeze_out(&mut self, output: &mut [u8]) -> usize;
536
537    /// Squeezes a partial byte from the XOF.
538    /// Output will be in the top `num_bits` bits of the returned u8 (ie Big Endian).
539    /// This is a final call and consumes self.
540    fn squeeze_partial_byte_final(self, num_bits: usize) -> Result<u8, HashError>;
541
542    fn squeeze_partial_byte_final_out(
543        self,
544        num_bits: usize,
545        output: &mut u8,
546    ) -> Result<(), HashError>;
547
548    /// Returns the maximum security strength that this KDF is capable of supporting, based on the underlying primitives.
549    fn max_security_strength(&self) -> SecurityStrength;
550}