mirror of
https://github.com/tlsnotary/tlsn.git
synced 2026-01-10 07:07:57 -05:00
refactor: add AEAD prove/verify + tag methods (#415)
* refactor: add prove/verify + tag methods * Update components/aead/src/aes_gcm/mod.rs Co-authored-by: dan <themighty1@users.noreply.github.com> --------- Co-authored-by: dan <themighty1@users.noreply.github.com>
This commit is contained in:
@@ -163,6 +163,27 @@ impl MpcAesGcm {
|
||||
|
||||
Ok(tag)
|
||||
}
|
||||
|
||||
/// Splits off the tag from the end of the payload and verifies it.
|
||||
async fn _verify_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
payload: &mut Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError> {
|
||||
let purported_tag = payload.split_off(payload.len() - AES_GCM_TAG_LEN);
|
||||
|
||||
let tag = self
|
||||
.compute_tag(explicit_nonce, payload.clone(), aad)
|
||||
.await?;
|
||||
|
||||
// Reject if tag is incorrect.
|
||||
if tag != purported_tag {
|
||||
return Err(AeadError::CorruptedTag);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -180,6 +201,7 @@ impl Aead for MpcAesGcm {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "info", err))]
|
||||
async fn decode_key_private(&mut self) -> Result<(), AeadError> {
|
||||
self.aes_ctr
|
||||
.decode_key_private()
|
||||
@@ -187,6 +209,7 @@ impl Aead for MpcAesGcm {
|
||||
.map_err(AeadError::from)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "info", err))]
|
||||
async fn decode_key_blind(&mut self) -> Result<(), AeadError> {
|
||||
self.aes_ctr
|
||||
.decode_key_blind()
|
||||
@@ -198,7 +221,10 @@ impl Aead for MpcAesGcm {
|
||||
self.aes_ctr.set_transcript_id(id)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err, ret))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(plaintext), err)
|
||||
)]
|
||||
async fn encrypt_public(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
@@ -220,7 +246,10 @@ impl Aead for MpcAesGcm {
|
||||
Ok(payload)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err, ret))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(plaintext), err)
|
||||
)]
|
||||
async fn encrypt_private(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
@@ -242,7 +271,7 @@ impl Aead for MpcAesGcm {
|
||||
Ok(payload)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err, ret))]
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err))]
|
||||
async fn encrypt_blind(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
@@ -264,118 +293,133 @@ impl Aead for MpcAesGcm {
|
||||
Ok(payload)
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err, ret))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(payload), err)
|
||||
)]
|
||||
async fn decrypt_public(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
mut ciphertext: Vec<u8>,
|
||||
mut payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError> {
|
||||
let purported_tag = ciphertext.split_off(ciphertext.len() - AES_GCM_TAG_LEN);
|
||||
|
||||
let tag = self
|
||||
.compute_tag(explicit_nonce.clone(), ciphertext.clone(), aad)
|
||||
self._verify_tag(explicit_nonce.clone(), &mut payload, aad)
|
||||
.await?;
|
||||
|
||||
// Reject if tag is incorrect
|
||||
if tag != purported_tag {
|
||||
return Err(AeadError::CorruptedTag);
|
||||
}
|
||||
|
||||
self.aes_ctr
|
||||
.decrypt_public(explicit_nonce, ciphertext)
|
||||
.decrypt_public(explicit_nonce, payload)
|
||||
.map_err(AeadError::from)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err, ret))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(payload), err)
|
||||
)]
|
||||
async fn decrypt_private(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
mut ciphertext: Vec<u8>,
|
||||
mut payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError> {
|
||||
let purported_tag = ciphertext.split_off(ciphertext.len() - AES_GCM_TAG_LEN);
|
||||
|
||||
let tag = self
|
||||
.compute_tag(explicit_nonce.clone(), ciphertext.clone(), aad)
|
||||
self._verify_tag(explicit_nonce.clone(), &mut payload, aad)
|
||||
.await?;
|
||||
|
||||
// Reject if tag is incorrect
|
||||
if tag != purported_tag {
|
||||
return Err(AeadError::CorruptedTag);
|
||||
}
|
||||
|
||||
self.aes_ctr
|
||||
.decrypt_private(explicit_nonce, ciphertext)
|
||||
.decrypt_private(explicit_nonce, payload)
|
||||
.map_err(AeadError::from)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "tracing", tracing::instrument(level = "trace", err, ret))]
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(payload), err)
|
||||
)]
|
||||
async fn decrypt_blind(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
mut ciphertext: Vec<u8>,
|
||||
mut payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError> {
|
||||
let purported_tag = ciphertext.split_off(ciphertext.len() - AES_GCM_TAG_LEN);
|
||||
|
||||
let tag = self
|
||||
.compute_tag(explicit_nonce.clone(), ciphertext.clone(), aad)
|
||||
self._verify_tag(explicit_nonce.clone(), &mut payload, aad)
|
||||
.await?;
|
||||
|
||||
// Reject if tag is incorrect
|
||||
if tag != purported_tag {
|
||||
return Err(AeadError::CorruptedTag);
|
||||
}
|
||||
|
||||
self.aes_ctr
|
||||
.decrypt_blind(explicit_nonce, ciphertext)
|
||||
.decrypt_blind(explicit_nonce, payload)
|
||||
.map_err(AeadError::from)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(payload), err)
|
||||
)]
|
||||
async fn verify_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
mut ciphertext: Vec<u8>,
|
||||
mut payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError> {
|
||||
let purported_tag = ciphertext.split_off(ciphertext.len() - AES_GCM_TAG_LEN);
|
||||
|
||||
let tag = self
|
||||
.compute_tag(explicit_nonce.clone(), ciphertext, aad)
|
||||
.await?;
|
||||
|
||||
// Reject if tag is incorrect
|
||||
if tag == purported_tag {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(AeadError::CorruptedTag)
|
||||
}
|
||||
self._verify_tag(explicit_nonce.clone(), &mut payload, aad)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(payload), err)
|
||||
)]
|
||||
async fn prove_plaintext(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
mut ciphertext: Vec<u8>,
|
||||
mut payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError> {
|
||||
ciphertext.truncate(ciphertext.len() - AES_GCM_TAG_LEN);
|
||||
self._verify_tag(explicit_nonce.clone(), &mut payload, aad)
|
||||
.await?;
|
||||
|
||||
self.prove_plaintext_no_tag(explicit_nonce, payload).await
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(ciphertext), err)
|
||||
)]
|
||||
async fn prove_plaintext_no_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError> {
|
||||
self.aes_ctr
|
||||
.prove_plaintext(explicit_nonce, ciphertext)
|
||||
.map_err(AeadError::from)
|
||||
.await
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(payload), err)
|
||||
)]
|
||||
async fn verify_plaintext(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
mut ciphertext: Vec<u8>,
|
||||
mut payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError> {
|
||||
ciphertext.truncate(ciphertext.len() - AES_GCM_TAG_LEN);
|
||||
self._verify_tag(explicit_nonce.clone(), &mut payload, aad)
|
||||
.await?;
|
||||
|
||||
self.verify_plaintext_no_tag(explicit_nonce, payload).await
|
||||
}
|
||||
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
tracing::instrument(level = "trace", skip(ciphertext), err)
|
||||
)]
|
||||
async fn verify_plaintext_no_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
) -> Result<(), AeadError> {
|
||||
self.aes_ctr
|
||||
.verify_plaintext(explicit_nonce, ciphertext)
|
||||
.map_err(AeadError::from)
|
||||
|
||||
@@ -114,12 +114,12 @@ pub trait Aead: Send {
|
||||
/// This method checks the authenticity of the ciphertext, tag and additional data.
|
||||
///
|
||||
/// * `explicit_nonce` - The explicit nonce to use for decryption.
|
||||
/// * `ciphertext` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `payload` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `aad` - Additional authenticated data.
|
||||
async fn decrypt_public(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError>;
|
||||
|
||||
@@ -128,12 +128,12 @@ pub trait Aead: Send {
|
||||
/// This method checks the authenticity of the ciphertext, tag and additional data.
|
||||
///
|
||||
/// * `explicit_nonce` - The explicit nonce to use for decryption.
|
||||
/// * `ciphertext` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `payload` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `aad` - Additional authenticated data.
|
||||
async fn decrypt_private(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError>;
|
||||
|
||||
@@ -142,12 +142,12 @@ pub trait Aead: Send {
|
||||
/// This method checks the authenticity of the ciphertext, tag and additional data.
|
||||
///
|
||||
/// * `explicit_nonce` - The explicit nonce to use for decryption.
|
||||
/// * `ciphertext` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `payload` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `aad` - Additional authenticated data.
|
||||
async fn decrypt_blind(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError>;
|
||||
|
||||
@@ -156,12 +156,12 @@ pub trait Aead: Send {
|
||||
/// This method checks the authenticity of the ciphertext, tag and additional data.
|
||||
///
|
||||
/// * `explicit_nonce` - The explicit nonce to use for decryption.
|
||||
/// * `ciphertext` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `payload` - The ciphertext and tag to authenticate and decrypt.
|
||||
/// * `aad` - Additional authenticated data.
|
||||
async fn verify_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError>;
|
||||
|
||||
@@ -176,8 +176,32 @@ pub trait Aead: Send {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `explicit_nonce`: The explicit nonce to use for the keystream.
|
||||
/// * `ciphertext`: The ciphertext to decrypt and prove.
|
||||
/// * `payload`: The ciphertext and tag to decrypt and prove.
|
||||
/// * `aad`: Additional authenticated data.
|
||||
async fn prove_plaintext(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<Vec<u8>, AeadError>;
|
||||
|
||||
/// Locally decrypts the provided ciphertext and then proves in ZK to the other party(s) that the
|
||||
/// plaintext is correct.
|
||||
///
|
||||
/// Returns the plaintext.
|
||||
///
|
||||
/// This method requires this party to know the encryption key, which can be achieved by calling
|
||||
/// the `decode_key_private` method.
|
||||
///
|
||||
/// # WARNING
|
||||
///
|
||||
/// This method does not verify the tag of the ciphertext. Only use this if you know what you're doing.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `explicit_nonce`: The explicit nonce to use for the keystream.
|
||||
/// * `ciphertext`: The ciphertext to decrypt and prove.
|
||||
async fn prove_plaintext_no_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
@@ -188,8 +212,26 @@ pub trait Aead: Send {
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `explicit_nonce`: The explicit nonce to use for the keystream.
|
||||
/// * `ciphertext`: The ciphertext to verify.
|
||||
/// * `payload`: The ciphertext and tag to verify.
|
||||
/// * `aad`: Additional authenticated data.
|
||||
async fn verify_plaintext(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
payload: Vec<u8>,
|
||||
aad: Vec<u8>,
|
||||
) -> Result<(), AeadError>;
|
||||
|
||||
/// Verifies the other party(s) can prove they know a plaintext which encrypts to the given ciphertext.
|
||||
///
|
||||
/// # WARNING
|
||||
///
|
||||
/// This method does not verify the tag of the ciphertext. Only use this if you know what you're doing.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `explicit_nonce`: The explicit nonce to use for the keystream.
|
||||
/// * `ciphertext`: The ciphertext to verify.
|
||||
async fn verify_plaintext_no_tag(
|
||||
&mut self,
|
||||
explicit_nonce: Vec<u8>,
|
||||
ciphertext: Vec<u8>,
|
||||
|
||||
Reference in New Issue
Block a user