Quasor

Quasor: A High-Security AEAD

Version 6.1.2

1. Introduction and Goals

Quasor is a high-security Authenticated Encryption with Associated Data (AEAD) scheme designed for modern applications where robustness and defense-in-depth are paramount. It is built on a Duplex Sponge construction using SHAKE256 and incorporates several advanced features to provide strong protection against both implementation errors and sophisticated attacks.

The primary design goals achieved in this version are:

2. Cryptographic Primitives

3. Key Derivation Process

The master key K for the cipher is derived from a user-provided password and a unique salt using Argon2id.

  1. Inputs: A user password (variable length) and a unique salt (minimum 8 bytes).
  2. Hashing: The Argon2id function is called with its default secure parameters to produce a 32-byte (256-bit) master key K.
  3. Security: This process is intentionally slow and memory-intensive to make offline brute-force and dictionary attacks computationally infeasible.

4. Domain Separation

Quasor v6.1 implements explicit domain separation to prevent cross-operation attacks and improve security analysis. All operations use 4-byte ASCII domain separators:

These domain separators ensure that different cryptographic operations cannot interfere with each other, providing defense-in-depth against implementation errors and cryptanalytic attacks.

5. Duplex Sponge Specification

State Management

The duplex sponge maintains internal state through explicit mode tracking:

  1. Initialization: Sponge begins in absorbing mode
  2. Absorbing → Squeezing: Apply SHAKE256 padding (0x1f), run Keccak-f[1600]
  3. Squeezing → Absorbing: Apply domain separation, run Keccak-f[1600]

Implementation Requirements

Implementations MUST:

6. Encryption Process

Inputs:

Procedure:

  1. Nonce Derivation (SIV):

    a. A 128-bit nonce N is derived by computing the keyed hash of the associated data and the plaintext using a secure, unambiguous serialization.

    b. The exact structure to be hashed is: len(A)   A   len(P)   P, where len() is the length in bytes, encoded as a 64-bit little-endian integer.

    c. For large inputs, the hashing of P is automatically parallelized using Rayon for high performance.

  2. Initialization:

    a. A new SHAKE256 sponge instance is initialized.

    b. The domain separator INIT is absorbed first for operation isolation.

    c. The master key K, the derived nonce N, and the associated data A are absorbed into the sponge.

    d. The rekey counter is initialized to 0.

  3. Encryption, Duplexing, and Rekeying:

    a. The domain separator ENCR is absorbed to indicate the start of encryption operations.

    b. The plaintext P is processed sequentially in efficient chunks of 1024 bytes.

    c. For each chunk, a keystream of the same size is squeezed from the sponge and XORed with the plaintext to produce ciphertext. The original plaintext chunk is then absorbed back into the sponge’s state.

    d. After each REKEY_INTERVAL (64 KiB) of data is processed, a rekeying step is performed:

    • The domain separator RKEY is absorbed
    • The current rekey counter (8 bytes, little-endian) is absorbed
    • 32 bytes are squeezed from the sponge to form an ephemeral key
    • The ephemeral key is immediately absorbed back into the state
    • The rekey counter is incremented
    • This provides forward secrecy and prevents state repetition
  4. Tag Generation:

    a. After all plaintext has been processed, the domain separator AUTH is absorbed.

    b. A 32-byte authentication tag T is squeezed from the sponge’s final state.

Outputs:

7. Decryption Process

Inputs:

Procedure:

  1. Initialization & Decryption:

    a. The decryption process mirrors the encryption process exactly: the sponge is initialized with the INIT domain separator, followed by K, N, and A.

    b. The rekey counter is initialized to 0.

    c. The domain separator ENCR is absorbed to indicate the start of decryption operations.

    d. The ciphertext is processed sequentially to reconstruct the plaintext, with identical rekeying steps performed along the way (including domain separation and counter incrementation).

  2. Tag Verification:

    a. After all ciphertext is processed, the domain separator AUTH is absorbed.

    b. An expected tag T’ is squeezed from the sponge’s final state.

    c. The received tag T must be compared to the computed tag T’ using a constant-time equality function. This is a critical step to prevent timing side-channel attacks. If they do not match, the process aborts, and an error is returned.

  3. Nonce Verification:

    a. If the tag is valid, the SIV nonce is re-derived using the newly decrypted plaintext P and the same length-prefixed serialization as in encryption.

    b. This re-derived nonce N’ is compared to the received nonce N using constant-time comparison. If they do not match, the process aborts, and an error is returned. This final check ensures the integrity of the entire message.

Output:

8. Enhanced Rekeying Protocol

The v6.1 rekeying protocol includes several improvements over previous versions:

Counter-Based State Management

Domain Separation

Procedure

perform_rekey():
    1. sponge.absorb(DOMAIN_RKEY)
    2. sponge.absorb(rekey_counter.to_le_bytes())
    3. ephemeral_key = sponge.squeeze(32)
    4. sponge.absorb(ephemeral_key)
    5. rekey_counter += 1

9. Security Parameters

10. Design Rationale and Security Considerations

11. Test Vectors

Known Answer Test (KAT)

Password: "QuasorKATPassword"
Salt: "QuasorKATSalt123"
Associated Data: "KnownAnswerTestAD"
Plaintext: "This is the official test vector for the Quasor AEAD."

Expected Results (v6.1):
Nonce: [to be generated with domain separation implementation]
Ciphertext: [to be generated with domain separation implementation]
Tag: [to be generated with domain separation implementation]

Empty Plaintext Test

Password: [32 zero bytes]
Salt: [16 zero bytes]
Associated Data: [empty]
Plaintext: [empty]

Expected Results (v6.1):
Nonce: [to be generated with domain separation implementation]
Ciphertext: [empty]
Tag: [to be generated with domain separation implementation]

12. Implementation Notes

Portability

Performance

Migration from Previous Versions

13. Version History

v6.1 (2025)

v6.0 (2024)

Earlier Versions