From 733c66ea458f6c439399b21f361175ef7002f9ca Mon Sep 17 00:00:00 2001 From: Monica Moniot Date: Tue, 30 Jan 2024 12:14:23 -0500 Subject: [PATCH] fixed mistakes in docs --- performance/src/application.rs | 13 ++-- performance/src/ratchet_state.rs | 28 ++++---- performance/src/zeta.rs | 2 +- reference/src/application.rs | 113 +++++++++++++++++++++++++++++-- reference/src/ratchet_state.rs | 28 ++++---- reference/src/zeta.rs | 2 +- whitepaper/zssp.pdf | Bin 426265 -> 426267 bytes whitepaper/zssp.tex | 8 +-- 8 files changed, 150 insertions(+), 44 deletions(-) diff --git a/performance/src/application.rs b/performance/src/application.rs index b69a699..b1f8bc3 100644 --- a/performance/src/application.rs +++ b/performance/src/application.rs @@ -231,7 +231,7 @@ pub trait ApplicationLayer: Sized { fn initiator_disallows_downgrade(&mut self, session: &Arc>) -> bool; /// Function to accept sessions after final negotiation. /// - /// The implementor must verify that three arguments, `remote_static_key`, `identity` and + /// The implementor must verify that the three arguments, `remote_static_key`, `identity` and /// optionally `fingerprint_data` all belong to the same remote peer, using whatever definition /// of "same remote peer" that the upper protocol chooses. /// `fingerprint_data` is an opaque type that is only `Some` if Alice sent us a ratchet @@ -359,14 +359,19 @@ pub trait ApplicationLayer: Sized { /// .map_err(to_err)?; /// let mut rows = stmt.query([peer]).map_err(to_err)?; /// if let Some(row) = rows.next().map_err(to_err)? { - /// let peer_fp1: &[u8] = row.get_ref(0).map_err(to_err)?.as_bytes().map_err(to_err)?; - /// let peer_fp2: Option<&[u8]> = row.get_ref(1).map_err(to_err)?.as_bytes_or_null().map_err(to_err)?; + /// let peer_fp1 = row.get_ref(0).map_err(to_err)?.as_bytes_or_null().map_err(to_err)?; + /// let peer_fp2 = row.get_ref(1).map_err(to_err)?.as_bytes_or_null().map_err(to_err)?; + /// let peer_fp1 = if let Some(fp1) = peer_fp1 { + /// fp1.try_into().map_err(to_err)? + /// } else { + /// &[0u8; RATCHET_SIZE] + /// }; /// let peer_fp2 = if let Some(fp2) = peer_fp2 { /// Some(fp2.try_into().map_err(to_err)?) /// } else { /// None /// }; - /// if !update_data.compare_fingerprints(peer_fp1.try_into().map_err(to_err)?, peer_fp2) { + /// if !update_data.compare_fingerprints(peer_fp1, peer_fp2) { /// return Ok(false); /// } /// } else { diff --git a/performance/src/ratchet_state.rs b/performance/src/ratchet_state.rs index 3f07290..08aee23 100644 --- a/performance/src/ratchet_state.rs +++ b/performance/src/ratchet_state.rs @@ -43,11 +43,11 @@ impl RatchetState { chain_len, } } - /// Creates a new "empty" ratchet state, where the ratchet fingerprint is the - /// empty string, the ratchet key is all zeros, and the chain length is 0. + /// Creates a new "zero" ratchet state, where the ratchet fingerprint is all zeros, + /// the ratchet key is all zeros, and the chain length is 0. /// /// This value is the default value of `RatchetState`. - pub fn empty() -> Self { + pub fn zero() -> Self { RatchetState { key: Zeroizing::new([0u8; RATCHET_SIZE]), fingerprint: Zeroizing::new([0u8; RATCHET_SIZE]), @@ -85,9 +85,7 @@ impl RatchetState { &self.key } /// The ratchet fingerprint for this ratchet state. - /// - /// If this returns `None` then the ratchet fingerprint is the empty string. - /// This is the "empty" ratchet state and the key will be all zeros. + /// It could be all zeros if this is the "zero" ratchet state. /// /// The ratchet fingerprint value is sensitive and should be hidden, /// but the security of ZSSP can survive having this value leaked. @@ -104,13 +102,13 @@ impl RatchetState { pub fn chain_len(&self) -> u64 { self.chain_len } - /// Returns true if this is the "empty" ratchet state, where the ratchet fingerprint is the - /// empty string, the ratchet key is all zeros, and the chain length is 0. - pub fn is_empty(&self) -> bool { + /// Returns true if this is the "zero" ratchet state, where the ratchet fingerprint is all zeros, + /// the ratchet key is all zeros, and the chain length is 0. + pub fn is_zero(&self) -> bool { secure_eq(self.fingerprint(), &[0u8; RATCHET_SIZE]) } /// Checks if the fingerprint of this ratchet state equals the - /// fingerprint contained in argument `rf`. + /// fingerprint contained in argument `rf`. /// /// Uses constant time equality. pub fn fingerprint_eq(&self, rf: &[u8; RATCHET_SIZE]) -> bool { @@ -134,7 +132,7 @@ impl RatchetState { } impl Default for RatchetState { fn default() -> Self { - Self::empty() + Self::zero() } } @@ -162,7 +160,7 @@ impl RatchetStates { /// /// This value is the default value of `RatchetStates`. pub fn new_initial_states() -> Self { - Self { state1: RatchetState::empty(), state2: None } + Self { state1: RatchetState::zero(), state2: None } } /// Creates a new initial pair of ratchet states from a one-time password. /// The first ratchet state will be derived from this password, while the second will be `None`. @@ -274,7 +272,7 @@ impl<'a> CompareAndSwap<'a> { /// There may be a second ratchet fingerprint to be deleted, which function /// `deleted_fingerprint2` will return. pub fn deleted_fingerprint1(&self) -> Option<&[u8; RATCHET_SIZE]> { - if self.cur_state1_was_just_deleted && !self.cur_state1.is_empty() { + if self.cur_state1_was_just_deleted && !self.cur_state1.is_zero() { return Some(self.cur_state1.fingerprint()); } None @@ -290,7 +288,7 @@ impl<'a> CompareAndSwap<'a> { pub fn deleted_fingerprint2(&self) -> Option<&[u8; RATCHET_SIZE]> { if self.cur_state2_was_just_deleted { if let Some(rf) = self.cur_state2 { - if !rf.is_empty() { + if !rf.is_zero() { return Some(rf.fingerprint()); } } @@ -305,7 +303,7 @@ impl<'a> CompareAndSwap<'a> { /// then the peer should be added to storage with the new ratchet states specified by this /// `CompareAndSwap` struct. pub fn cur_is_initial_states(&self) -> bool { - self.cur_state1.is_empty() && self.cur_state2.is_none() + self.cur_state1.is_zero() && self.cur_state2.is_none() } /// Compares the ratchet fingerprints of `cur_state1` and `cur_state2` with `rf1` and `rf2`. /// If they are equal this function will return `true`. diff --git a/performance/src/zeta.rs b/performance/src/zeta.rs index bd8f7d2..1d42bc4 100644 --- a/performance/src/zeta.rs +++ b/performance/src/zeta.rs @@ -870,7 +870,7 @@ pub(crate) fn received_x3_trans>( let mut should_warn_missing_ratchet = false; if (zeta.ratchet_state != state1) & (Some(&zeta.ratchet_state) != state2.as_ref()) { - if !responder_disallows_downgrade && zeta.ratchet_state.is_empty() { + if !responder_disallows_downgrade && zeta.ratchet_state.is_zero() { should_warn_missing_ratchet = true; } else { if !responder_silently_rejects { diff --git a/reference/src/application.rs b/reference/src/application.rs index 67c0151..d3acf59 100644 --- a/reference/src/application.rs +++ b/reference/src/application.rs @@ -155,6 +155,9 @@ pub trait ApplicationLayer: Sized { /// If this function is configured to always return true, it means peers will not be able to /// connect to us unless they had a prior-established ratchet key with us. This is the best way /// for the paranoid to enforce a manual allow-list. + /// + /// Corresponds to the "Hello Requires Recognized Ratchet, π_1" security flag of Transition + /// Algorithm 2 within the ZSSP whitepaper. fn hello_requires_recognized_ratchet(&mut self) -> bool; /// This function is called if we, as Alice, attempted to open a session with Bob using a /// non-empty ratchet key, but Bob does not have this ratchet key and wants to downgrade @@ -171,13 +174,23 @@ pub trait ApplicationLayer: Sized { /// least one party is misconfigured and got their ratchet keys corrupted or lost, or Bob has /// been compromised and is being impersonated. An attacker must at least have Bob's private /// static key to be able to ask Alice to downgrade. + /// + /// Corresponds to the "Initiator Disallows Downgrade, π_2" security flag of Transition + /// Algorithm 3 within the ZSSP whitepaper. fn initiator_disallows_downgrade(&mut self, session: &Arc>) -> bool; /// Function to accept sessions after final negotiation. - /// The second argument is the identity that the remote peer sent us. The application - /// must verify this identity is associated with the remote peer's static key. + /// + /// The implementor must verify that `remote_static_key` and `identity` all belong to the same + /// remote peer, using whatever definition + /// of "same remote peer" that the upper protocol chooses. + /// `fingerprint_data` is an opaque type that is only `Some` if Alice sent us a ratchet + /// fingerprint that was successfully restored by `restore_by_fingerprint`. + /// /// To prevent desync, if this function specifies that we should connect, no other open session /// with the same remote peer must exist. Drop or call expire on any pre-existing sessions /// before returning. + /// + /// Corresponds to the **Accept** call of Transition Algorithm 4 within the ZSSP whitepaper. fn check_accept_session( &mut self, remote_static_key: &::PublicKey, @@ -190,6 +203,20 @@ pub trait ApplicationLayer: Sized { /// /// If a ratchet state with a matching fingerprint could not be found, this function should /// return `Ok(None)`. + /// + /// This function can also return an opaque `FingerprintData` object. If Alice continues to connect + /// with us, then this object will be passed to `check_accept_session` and `restore_by_identity`. + /// This is useful if the ratchet fingerprint was derived from a one-time password, in which + /// case `FingerprintData` can contain metadata regarding the one-time password. This can be + /// used by `check_accept_session` and `restore_by_identity` to perform additional + /// authentication checks, such as validating the one-time password as an invitation code. + /// + /// `FingerprintData` can also be used with extreme caution to cache database resources that can + /// speed up the expected future calls to `check_accept_session` and `restore_by_identity`. + /// If this is done, the implementor is required in `check_accept_session` to verify that the + /// cached resources in `FingerprintData` indeed belong to the specified remote peer. + /// + /// Corresponds to the **Restore** call of Transition Algorithm 2 within the ZSSP whitepaper. fn restore_by_fingerprint( &mut self, ratchet_fingerprint: &[u8; RATCHET_SIZE], @@ -198,8 +225,9 @@ pub trait ApplicationLayer: Sized { /// This function will be called whenever Alice attempts to open a session, or Bob attempts /// to verify Alice's identity. /// - /// If the peer's ratchet states could not be could, this function should return - /// `RatchetState::new_initial_states()`. + /// If the peer's ratchet states could not be found, this function should return `None`. + /// A return value of `None` is equivalent to a return value of + /// `Some(RatchetState::new_initial_states())`. /// /// If a one-time-password has been pre-shared with this peer, `RatchetState::new_otp_states(...)` /// should be pre-saved to the storage backend as if it is a normal ratchet state. @@ -208,6 +236,8 @@ pub trait ApplicationLayer: Sized { /// This function is not responsible for deciding whether or not to connect to this remote peer. /// Filtering peers should be done by the caller to `Context::open` as well as by the /// function `ApplicationLayer::check_accept_session`. + /// + /// Corresponds to the **Restore** call of Transition Algorithm 1 and 4 within the ZSSP whitepaper. fn restore_by_identity( &mut self, remote_static_key: &::PublicKey, @@ -242,6 +272,81 @@ pub trait ApplicationLayer: Sized { /// it should be assumed that they also have the same ratchet key. /// /// The implementations of `PartialEq` for `RatchetState` and `RatchetStates` do this by default. + /// + /// # Example + /// The following code is an example of how to implement this database operation with the + /// library `rustqlite`, an interface for SQLite in rust. + /// This code will not work out-of-the-box, it must be adapted based on how your application + /// structures its SQLite database. + /// Notably, this code lacks a means of securely indexing ratchet fingerprints. + /// The function `get_peer_primary_key` is a placeholder for however your application defines + /// the SQL primary key for a peer. The function `get_sql_conn` is a placeholder getter method + /// on `self` for retrieving the database connection object. + /// ```rs + /// fn to_err(e: E) -> Error { + /// Error::new(std::io::ErrorKind::Other, e) + /// } + /// + /// fn save_ratchet_state( + /// &mut self, + /// remote_static_key: &P384PublicKey, + /// session_data: &Peer, + /// update_data: CompareAndSwap<'_>, + /// ) -> Result { + /// let peer = get_peer_primary_key(remote_static_key, session_data); + /// let mut conn = get_sql_conn(self); + /// // rustqlite will rollback this transaction if this struct is dropped. + /// let trans = conn + /// .transaction_with_behavior(rusqlite::TransactionBehavior::Immediate) + /// .map_err(to_err)?; + /// { + /// // Compare + /// let mut stmt = trans + /// .prepare_cached("SELECT ratchet_fp1, ratchet_fp2 FROM peers WHERE peer = ?1") + /// .map_err(to_err)?; + /// let mut rows = stmt.query([peer]).map_err(to_err)?; + /// if let Some(row) = rows.next().map_err(to_err)? { + /// let peer_fp1 = row.get_ref(0).map_err(to_err)?.as_bytes_or_null().map_err(to_err)?; + /// let peer_fp2 = row.get_ref(1).map_err(to_err)?.as_bytes_or_null().map_err(to_err)?; + /// let peer_fp1 = if let Some(fp1) = peer_fp1 { + /// fp1.try_into().map_err(to_err)? + /// } else { + /// &[0u8; RATCHET_SIZE] + /// }; + /// let peer_fp2 = if let Some(fp2) = peer_fp2 { + /// Some(fp2.try_into().map_err(to_err)?) + /// } else { + /// None + /// }; + /// if !update_data.compare_fingerprints(peer_fp1, peer_fp2) { + /// return Ok(false); + /// } + /// } else { + /// return Ok(false); + /// } + /// } + /// { + /// // Swap + /// let ns1 = update_data.new_state1; + /// let ns2 = update_data.new_state2; + /// let mut stmt = trans.prepare_cached("UPDATE peers SET ratchet_fp1 = ?1, ratchet_key1 = ?2, chain_len1 = ?3, ratchet_fp2 = ?4, ratchet_key2 = ?5, chain_len2 = ?6 WHERE salted_addr = ?7").map_err(to_err)?; + /// stmt.execute(( + /// ns1.fingerprint(), + /// ns1.key(), + /// ns1.chain_len(), + /// ns2.map(RatchetState::fingerprint), + /// ns2.map(RatchetState::key), + /// ns2.map(RatchetState::chain_len), + /// salted_addr, + /// )) + /// .map_err(to_err)?; + /// } + /// // SQLite does its best to make sure committed transactions are actually written + /// // to disk: https://www.sqlite.org/howtocorrupt.html. + /// trans.commit().map_err(to_err)?; + /// Ok(true) + /// } + /// ``` fn save_ratchet_state( &mut self, remote_static_key: &::PublicKey, diff --git a/reference/src/ratchet_state.rs b/reference/src/ratchet_state.rs index 204852e..573767a 100644 --- a/reference/src/ratchet_state.rs +++ b/reference/src/ratchet_state.rs @@ -42,11 +42,11 @@ impl RatchetState { chain_len, } } - /// Creates a new "empty" ratchet state, where the ratchet fingerprint is the - /// empty string, the ratchet key is all zeros, and the chain length is 0. + /// Creates a new "zero" ratchet state, where the ratchet fingerprint is all zeros, + /// the ratchet key is all zeros, and the chain length is 0. /// /// This value is the default value of `RatchetState`. - pub fn empty() -> Self { + pub fn zero() -> Self { RatchetState { key: Zeroizing::new([0u8; RATCHET_SIZE]), fingerprint: Zeroizing::new([0u8; RATCHET_SIZE]), @@ -82,9 +82,7 @@ impl RatchetState { &self.key } /// The ratchet fingerprint for this ratchet state. - /// - /// If this returns `None` then the ratchet fingerprint is the empty string. - /// This is the "empty" ratchet state and the key will be all zeros. + /// It could be all zeros if this is the "zero" ratchet state. /// /// The ratchet fingerprint value is sensitive and should be hidden, /// but the security of ZSSP can survive having this value leaked. @@ -101,13 +99,13 @@ impl RatchetState { pub fn chain_len(&self) -> u64 { self.chain_len } - /// Returns true if this is the "empty" ratchet state, where the ratchet fingerprint is the - /// empty string, the ratchet key is all zeros, and the chain length is 0. - pub fn is_empty(&self) -> bool { + /// Returns true if this is the "zero" ratchet state, where the ratchet fingerprint is all zeros, + /// the ratchet key is all zeros, and the chain length is 0. + pub fn is_zero(&self) -> bool { secure_eq(self.fingerprint(), &[0u8; RATCHET_SIZE]) } /// Checks if the fingerprint of this ratchet state equals the - /// fingerprint contained in argument `rf`. + /// fingerprint contained in argument `rf`. /// /// Uses constant time equality. pub fn fingerprint_eq(&self, rf: &[u8; RATCHET_SIZE]) -> bool { @@ -131,7 +129,7 @@ impl RatchetState { } impl Default for RatchetState { fn default() -> Self { - Self::empty() + Self::zero() } } @@ -159,7 +157,7 @@ impl RatchetStates { /// /// This value is the default value of `RatchetStates`. pub fn new_initial_states() -> Self { - Self { state1: RatchetState::empty(), state2: None } + Self { state1: RatchetState::zero(), state2: None } } /// Creates a new initial pair of ratchet states from a one-time password. /// The first ratchet state will be derived from this password, while the second will be `None`. @@ -271,7 +269,7 @@ impl<'a> CompareAndSwap<'a> { /// There may be a second ratchet fingerprint to be deleted, which function /// `deleted_fingerprint2` will return. pub fn deleted_fingerprint1(&self) -> Option<&[u8; RATCHET_SIZE]> { - if self.cur_state1_was_just_deleted && !self.cur_state1.is_empty() { + if self.cur_state1_was_just_deleted && !self.cur_state1.is_zero() { return Some(self.cur_state1.fingerprint()); } None @@ -287,7 +285,7 @@ impl<'a> CompareAndSwap<'a> { pub fn deleted_fingerprint2(&self) -> Option<&[u8; RATCHET_SIZE]> { if self.cur_state2_was_just_deleted { if let Some(rf) = self.cur_state2 { - if !rf.is_empty() { + if !rf.is_zero() { return Some(rf.fingerprint()); } } @@ -302,7 +300,7 @@ impl<'a> CompareAndSwap<'a> { /// then the peer should be added to storage with the new ratchet states specified by this /// `CompareAndSwap` struct. pub fn cur_is_initial_states(&self) -> bool { - self.cur_state1.is_empty() && self.cur_state2.is_none() + self.cur_state1.is_zero() && self.cur_state2.is_none() } /// Compares the ratchet fingerprints of `cur_state1` and `cur_state2` with `rf1` and `rf2`. /// If they are equal this function will return `true`. diff --git a/reference/src/zeta.rs b/reference/src/zeta.rs index 776e194..8f50a3f 100644 --- a/reference/src/zeta.rs +++ b/reference/src/zeta.rs @@ -734,7 +734,7 @@ pub(crate) fn received_x3_trans>( let mut should_warn_missing_ratchet = false; if (zeta.ratchet_state != state1) & (Some(&zeta.ratchet_state) != state2.as_ref()) { - if !responder_disallows_downgrade && zeta.ratchet_state.is_empty() { + if !responder_disallows_downgrade && zeta.ratchet_state.is_zero() { should_warn_missing_ratchet = true; } else { if !responder_silently_rejects { diff --git a/whitepaper/zssp.pdf b/whitepaper/zssp.pdf index dbc27e17ee000e7e21fcf35eab79285a16181210..03489f3e3d76c5b340fbe19970b0d5cf6080b4b3 100644 GIT binary patch delta 28720 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 delta 28728 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 diff --git a/whitepaper/zssp.tex b/whitepaper/zssp.tex index 43fb96f..d83ee9e 100644 --- a/whitepaper/zssp.tex +++ b/whitepaper/zssp.tex @@ -98,7 +98,7 @@ To motivate the need for ASKs further, consider that many authenticated key exch The maintainers of the Noise protocol are aware of the need for ASKs, and are in the process of extending the protocol with an ASK mechanism \cite{noise_ask}. However, at this point in time this mechanism is still unofficial and may be replaced. It also uses specific capabilities of \text{HKDF} that \text{KBKDF} does not have. For that reason we have created our own ASK extension to the Noise protocol, based on the unofficial mechanism. -We add a function, $\text{GetAsk}(\texttt{label})$, to the Noise protocol that takes as input a static label, and produces as output two 256-bit keys. This function is implemented as a component of the Noise handshake state machine, and so it has access to the most recent values of the Noise handshake hash, \texttt{h}, and the Noise chaining key, \texttt{ck}. To preserve consistency with `MixKey' and `Split', we will produce two 512-bit hashes, and then truncate each to 256-bits to produce two keys. +We add a function, $\text{GetAsk}(\texttt{label})$, to the Noise protocol that takes as input a static string, and produces as output two 256-bit keys. This function is implemented as a component of the Noise handshake state machine, and so it has access to the most recent values of the Noise handshake hash, \texttt{h}, and the Noise chaining key, \texttt{ck}. To preserve consistency with `MixKey' and `Split', we will produce two 512-bit hashes, and then truncate each to 256-bits to produce two keys. $$\text{GetAsk}(\texttt{label}) := \text{KBKDF}(\texttt{h}, \texttt{label}, \texttt{ck}, 1024).$$ @@ -519,15 +519,15 @@ The following are the 4 cryptographic primitives ZKE is based upon. We will be a \end{definition} \begin{definition}[H][KBKDF \cite{fips_kbkdf}] - Let $\KDF(\textit{K}_{\textit{IN}}, \textit{Label}, \textit{Context}, N)$ be the KBKDF key derivation algorithm, instantiated in HMAC-Counter mode using SHA-512. Variable $\textit{K}_{\textit{IN}}$ is the input key material, $\textit{Label}$ is some static label, $\textit{Context}$ is additional input key material, and $N$ is the number of 512-bit outputs to be produced. $\KDF(\textit{K}_{\textit{IN}}, \textit{Label}, \textit{Context}, N)$ produces as output $(x_1,\ldots,x_N)$, a tuple of $N$ 512-bit outputs. + Let $\KDF(\textit{K}_{\textit{IN}}, \textit{Label}, \textit{Context}, N)$ be the KBKDF key derivation algorithm, instantiated in HMAC-Counter mode using SHA-512. Variable $\textit{K}_{\textit{IN}}$ is the input key material, $\textit{Label}$ is some static string, $\textit{Context}$ is additional input key material, and $N$ is the number of 512-bit outputs to be produced. $\KDF(\textit{K}_{\textit{IN}}, \textit{Label}, \textit{Context}, N)$ produces as output $(x_1,\ldots,x_N)$, a tuple of $N$ 512-bit outputs. - Given $i\in \{1,\ldots,N\}$, we will use the notation $\KDF(\textit{K}_{\textit{IN}}, \textit{Label}, \textit{Context}, N)_i$ to refer to the $i$th output of $\KDF$. When assigning a single 512-bit output to a variable or field that is 256-bits in size, it is assumed that the output is being truncated to just the first 256-bits. + Given $i\in \{1,\ldots,N\}$, we will use the notation $\KDF(\textit{K}_{\textit{IN}}, \textit{Label}, \textit{Context}, N)_i$ to refer to the $i$th output of $\KDF$. When assigning a 512-bit output to a variable or field that is 256-bits in size, it is assumed that the output is being truncated to just the first 256-bits. So $k\gets \KDF(x, l, y, 3)_2$ represents computing KBKDF on inputs $\textit{K}_{\textit{IN}}= x,\, \textit{Label}=l,\, \textit{Context}=y$ and $L=3\cdot 512$, and setting variable $k$ equal to bits $512$ to $1023$ of the output. If $k$ is a variable of size 256-bits, then $k$ is set equal to bits $512$ to $767$ of the output. \end{definition} \begin{definition}[H][AES-GCM \cite{fips_aesgcm}] - Let $\AEAD(K, N, H, M)$ be the AES-GCM Authenticated Encryption with Additional Data algorithm, where $K$ is the encryption key, $N$ is the nonce or IV, $H$ is the additional authentication data, and $M$ is the plaintext message to be encrypted. $\AEAD(K, N, H, M)$ produces as output $c||t$, a ciphertext, $c$, concatenated with its 128-bit (16 byte) authentication tag, $t$. + Let $\AEAD(K, N, H, M)$ be the AES-GCM Authenticated Encryption with Additional Data algorithm, where $K$ is the encryption key, $N$ is the AEAD nonce, $H$ is the additional authentication data, and $M$ is the plaintext message to be encrypted. $\AEAD(K, N, H, M)$ produces as output $c||t$, a ciphertext, $c$, concatenated with its 128-bit (16 byte) authentication tag, $t$. \end{definition} \begin{definition}[H][P384 \cite{fips_p384}]