mirror of
https://github.com/saymrwulf/betrusted-curve25519-dalek-source.git
synced 2026-09-04 20:24:07 +00:00
* Added items to changelog for 2.0 release * Removed unnecessary uses of std in doctests * Gated `Context` behind `digest` * Fixed noncompiling doctest when only `digest` is enabled * README feature flag list mostly done * Copied changelog to readme * Redid the malleability section in README * Added CONTRIBUTING.md * Bumped version number to 2.0.0-pre.0; small changes to README * Updated changelog for #277 * Added pem feature description Co-authored-by: pinkforest(she/her) <36498018+pinkforest@users.noreply.github.com>
110 lines
3.6 KiB
Rust
110 lines
3.6 KiB
Rust
use crate::{InternalError, SignatureError};
|
|
|
|
/// Ed25519 contexts as used by Ed25519ph.
|
|
///
|
|
/// Contexts are domain separator strings that can be used to isolate uses of
|
|
/// the algorithm between different protocols (which is very hard to reliably do
|
|
/// otherwise) and between different uses within the same protocol.
|
|
///
|
|
/// To create a context, call either of the following:
|
|
///
|
|
/// - [`SigningKey::with_context`](crate::SigningKey::with_context)
|
|
/// - [`VerifyingKey::with_context`](crate::VerifyingKey::with_context)
|
|
///
|
|
/// For more information, see [RFC8032 § 8.3](https://www.rfc-editor.org/rfc/rfc8032#section-8.3).
|
|
///
|
|
/// # Example
|
|
///
|
|
#[cfg_attr(all(feature = "digest", feature = "rand_core"), doc = "```")]
|
|
#[cfg_attr(
|
|
any(not(feature = "digest"), not(feature = "rand_core")),
|
|
doc = "```ignore"
|
|
)]
|
|
/// # fn main() {
|
|
/// use ed25519_dalek::{Signature, SigningKey, VerifyingKey, Sha512};
|
|
/// # use curve25519_dalek::digest::Digest;
|
|
/// # use rand::rngs::OsRng;
|
|
/// use ed25519_dalek::{DigestSigner, DigestVerifier};
|
|
///
|
|
/// # let mut csprng = OsRng;
|
|
/// # let signing_key = SigningKey::generate(&mut csprng);
|
|
/// # let verifying_key = signing_key.verifying_key();
|
|
/// let context_str = b"Local Channel 3";
|
|
/// let prehashed_message = Sha512::default().chain_update(b"Stay tuned for more news at 7");
|
|
///
|
|
/// // Signer
|
|
/// let signing_context = signing_key.with_context(context_str).unwrap();
|
|
/// let signature = signing_context.sign_digest(prehashed_message.clone());
|
|
///
|
|
/// // Verifier
|
|
/// let verifying_context = verifying_key.with_context(context_str).unwrap();
|
|
/// let verified: bool = verifying_context
|
|
/// .verify_digest(prehashed_message, &signature)
|
|
/// .is_ok();
|
|
///
|
|
/// # assert!(verified);
|
|
/// # }
|
|
/// ```
|
|
#[derive(Clone, Debug)]
|
|
pub struct Context<'k, 'v, K> {
|
|
/// Key this context is being used with.
|
|
key: &'k K,
|
|
|
|
/// Context value: a bytestring no longer than 255 octets.
|
|
value: &'v [u8],
|
|
}
|
|
|
|
impl<'k, 'v, K> Context<'k, 'v, K> {
|
|
/// Maximum length of the context value in octets.
|
|
pub const MAX_LENGTH: usize = 255;
|
|
|
|
/// Create a new Ed25519ph context.
|
|
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))
|
|
}
|
|
}
|
|
|
|
/// Borrow the key.
|
|
pub fn key(&self) -> &'k K {
|
|
self.key
|
|
}
|
|
|
|
/// Borrow the context string value.
|
|
pub fn value(&self) -> &'v [u8] {
|
|
self.value
|
|
}
|
|
}
|
|
|
|
#[cfg(all(test, feature = "digest"))]
|
|
mod test {
|
|
use crate::{Signature, SigningKey, VerifyingKey};
|
|
use curve25519_dalek::digest::Digest;
|
|
use ed25519::signature::{DigestSigner, DigestVerifier};
|
|
use rand::rngs::OsRng;
|
|
use sha2::Sha512;
|
|
|
|
#[test]
|
|
fn context_correctness() {
|
|
let mut csprng = OsRng;
|
|
let signing_key: SigningKey = SigningKey::generate(&mut csprng);
|
|
let verifying_key: VerifyingKey = signing_key.verifying_key();
|
|
|
|
let context_str = b"Local Channel 3";
|
|
let prehashed_message = Sha512::default().chain_update(b"Stay tuned for more news at 7");
|
|
|
|
// Signer
|
|
let signing_context = signing_key.with_context(context_str).unwrap();
|
|
let signature: Signature = signing_context.sign_digest(prehashed_message.clone());
|
|
|
|
// Verifier
|
|
let verifying_context = verifying_key.with_context(context_str).unwrap();
|
|
let verified: bool = verifying_context
|
|
.verify_digest(prehashed_message, &signature)
|
|
.is_ok();
|
|
|
|
assert!(verified);
|
|
}
|
|
}
|