use crate::{InternalError, SignatureError};
#[cfg_attr(all(feature = "digest", feature = "rand_core"), doc = "```")]
#[cfg_attr(
any(not(feature = "digest"), not(feature = "rand_core")),
doc = "```ignore"
)]
#[derive(Clone, Debug)]
pub struct Context<'k, 'v, K> {
key: &'k K,
value: &'v [u8],
}
impl<'k, 'v, K> Context<'k, 'v, K> {
pub const MAX_LENGTH: usize = 255;
pub(crate) fn new(key: &'k K, value: &'v [u8]) -> Result<Self, SignatureError> {
if value.len() <= Self::MAX_LENGTH {
Ok(Self { key, value })
} else {
Err(SignatureError::from(InternalError::PrehashedContextLength))
}
}
pub fn key(&self) -> &'k K {
self.key
}
pub fn value(&self) -> &'v [u8] {
self.value
}
}
#[cfg(all(test, feature = "digest"))]
mod test {
#![allow(clippy::unwrap_used)]
use crate::{Signature, SigningKey, VerifyingKey};
use curve25519_dalek::digest::Digest;
use getrandom::SysRng;
use rand_core::UnwrapErr;
use sha2::Sha512;
use signature::{DigestSigner, DigestVerifier};
#[test]
fn context_correctness() {
let mut csprng = UnwrapErr(SysRng);
let signing_key: SigningKey = SigningKey::generate(&mut csprng);
let verifying_key: VerifyingKey = signing_key.verifying_key();
let context_str = b"Local Channel 3";
let message = b"Stay tuned for more news at 7";
let signing_context = signing_key.with_context(context_str).unwrap();
let signature: Signature =
signing_context.sign_digest(|digest: &mut Sha512| digest.update(message));
let verifying_context = verifying_key.with_context(context_str).unwrap();
let verified: bool = verifying_context
.verify_digest(
|digest: &mut Sha512| {
digest.update(message);
Ok(())
},
&signature,
)
.is_ok();
assert!(verified);
}
}