GcmSiv

Mojo struct 🡭

GcmSiv

@memory_only
struct GcmSiv[C: BlockCipherDecryptable & BlockCipherEncryptable & Copyable & Deinitable, G: UniversalHashable & Copyable & Deinitable]

AES-GCM-SIV nonce-misuse-resistant authenticated encryption (RFC 8452).

Key differences from Gcm:

  • The nonce is fixed at 96 bits (12 bytes).
  • The tag is fixed at 128 bits (16 bytes); no truncation is permitted.
  • The cipher passed at construction is keyed with the key-generating key. The per-record message-authentication key (POLYVAL key) and message-encryption key are derived from that key together with the nonce, so they are recomputed for this instance’s nonce rather than prebuilt the way Gcm prebuilds its GHASH key (H = E_K(0)).
  • Authentication uses POLYVAL (the byte-reflected dual of GHASH), not GHASH.

Note: GCM-SIV is defined only for block ciphers with a 128-bit block size.

RFC 8452: https://www.rfc-editor.org/rfc/rfc8452

Aliases

  • BLOCK_SIZE = C.BLOCK_SIZE
  • NONCE_SIZE = Int(12)
  • TAG_SIZE = Int(16)

Parameters

  • C (BlockCipherDecryptable & BlockCipherEncryptable & Copyable & Deinitable)
  • G (UniversalHashable & Copyable & Deinitable)

Implemented traits

AeadDecryptable, AeadEncryptable, AnyType, Copyable, Deinitable, Movable

Methods

create

@staticmethod
fn def create[KEY_SIZE: Int, //](cipher_init: T, key_generating_key: Array[UInt8, KEY_SIZE], nonce: Array[UInt8, Int(12)]) -> Self

Initialize GCM-SIV with the key-generating-key cipher and nonce.

Parameters:

  • KEY_SIZE (Int)

Args:

  • cipher_init (T)
  • key_generating_key (Array[UInt8, KEY_SIZE])
  • nonce (Array[UInt8, Int(12)])

Returns:

Self

Raises:

encrypt

fn def encrypt[aad_o: Origin[mut=aad_o.mut], o: MutOrigin](mut self, aad: Span[UInt8, aad_o], data: Span[UInt8, o]) -> Array[UInt8, __result__.TAG_SIZE]

Encrypt data in place and return the 16-byte tag.

Unlike GCM, the tag is computed first: POLYVAL absorbs aad and the plaintext, the result is combined with the nonce and encrypted to form the synthetic tag, and that tag (with its top bit cleared) seeds the CTR keystream used to encrypt data.

Parameters:

  • aad_o (Origin[mut=mut])
  • o (MutOrigin)

Args:

  • self (Self)
  • aad (Span[UInt8, aad_o])
  • data (Span[UInt8, o])

Returns:

Array[UInt8, __result__.TAG_SIZE]

Raises:

decrypt

fn def decrypt[aad_o: Origin[mut=aad_o.mut], o: MutOrigin](mut self, aad: Span[UInt8, aad_o], data: Span[UInt8, o], tag: Array[UInt8])

Decrypt data in place, then verify tag.

Because the tag seeds the CTR counter, GCM-SIV must decrypt before it can recompute the expected tag. The recomputed tag is compared against tag in constant time; on mismatch this raises and the recovered plaintext is re-encrypted back to the input ciphertext (it cannot be left untouched the way Gcm.decrypt leaves it), so a tampered data is never exposed.

Parameters:

  • aad_o (Origin[mut=mut])
  • o (MutOrigin)

Args:

  • self (Self)
  • aad (Span[UInt8, aad_o])
  • data (Span[UInt8, o])
  • tag (Array[UInt8])

Raises: