Skip to content
/ MACE Public

A Lightweight high-performance symmetric encryption framework designed to provide Full Diffusion

License

Notifications You must be signed in to change notification settings

MHSarmadi/MACE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MACE (MAC Assisted Chunked Encryption algorithm)

MACE is a lightweight, high-performance symmetric encryption framework designed for cryptographic systems. It provides a flexible core encryption primitive based on the BLAKE3 hash function and layered round transformations.

This implementation is intentionally low-level and avoids reliance on common encryption frameworks (like AES-GCM or ChaCha20-Poly1305). Instead, it focuses on deterministic, composable, and structurally reversible transformations that make it easier to experiment with advanced cryptographic architectures.


⚙️ Overview

MACE operates as a reversible transformation engine that processes data in fixed-size chunks. Each chunk of plaintext (or ciphertext) is combined with its neighbors and hashed through BLAKE3 to produce diffusion and nonlinearity. The process repeats across several rounds, where each round depends on a difficulty parameter.

Unlike conventional ciphers, MACE:

  • Derives its key stream dynamically from a BLAKE3 hasher.
  • Uses the key and salt to generate a session-specific keyed BLAKE3 instance.
  • Performs forward and backward transformations that are mathematically invertible.

The structure of MACE makes it adaptable for use in deterministic or randomized encryption, AEAD-like integrity protection, and even mixin-based key diversification.


🔐 Key Properties

Property Description
Algorithm Base BLAKE3 (keyed + deriveKey)
Mode of Operation Chunk-based iterative diffusion rounds
Encryption/Decryption Fully symmetric and reversible
Determinism Optional (for reproducible ciphertexts)
Salt 12 bytes random (omitted if deterministic)
Chunk Size 32 or 64 bytes (auto-selected)
Security Layer Strength depends on difficulty (round depth)

🧩 Variants

1. MACE_Encrypt / MACE_Decrypt

The base encryption and decryption functions. They perform reversible transformation using a key, context, salt, and difficulty.

2. MACE_Encrypt_MIXIN / MACE_Decrypt_MIXIN

Adds a mixin input that is folded into key derivation. It’s useful for session binding or additional entropy but does not act as authenticated data.

3. MACE_Encrypt_AEAD / MACE_Decrypt_AEAD

Extends MACE with a MAC tag generated from the final keyed BLAKE3 state. The tag authenticates both the ciphertext and the difficulty value. Use this when authenticity matters.

4. MACE_Encrypt_MIXIN_AEAD / MACE_Decrypt_MIXIN_AEAD

Combines both mixin-based key diversification and AEAD-style authentication. The strongest and safest variant.


⚠️ Security Warnings

  1. Always check the valid flag from AEAD decryptions before using the plaintext. (This implementation always return decrypted value, even if its totally broken - avoides time attacks but could break the functionality if you forget to check valid flag)
  2. Deterministic mode leaks message equality and should be used only when intentional.
  3. Input buffers are modified in-place. Make a copy if you need to preserve input.
  4. Padding errors return truncated data even when invalid. Always check the returned error.

🧠 Internal Design Summary

Each encryption round works as follows:

  1. Split the data into chunks of fixed size (32 or 64 bytes).
  2. Process from the last chunk to the first (for encryption) and vice versa for decryption.
  3. For each chunk, compute a BLAKE3 hash of its neighbor chunk(s) and round/chunk indices.
  4. XOR the digest with the current chunk to introduce diffusion.
  5. Repeat for multiple rounds based on the difficulty parameter.

The decryption process mirrors this exactly but iterates rounds in reverse order.


🔧 Example Usage

// Encrypt
data := []byte("hello world")
key := []byte("supersecretkey123")
cipher, salt := MACE_Encrypt(key, data, "demo", 4, false)

// Decrypt
plain, err := MACE_Decrypt(key, cipher, salt, "demo", 4)
if err != nil {
    panic(err)
}
fmt.Println(string(plain))

🧰 Notes for Developers

  • Difficulty controls the number of rounds: rounds = 2*difficulty + 3.
  • Salt is 12 bytes and random unless deterministic mode is on.
  • Key derivation combines: key + salt + context using BLAKE3 deriveKey.
  • MACE is fully reversible — no internal state loss.
  • The AEAD tag is 16 bytes derived from keyed BLAKE3.

📄 License

This project is licensed under the GNU LGPL v3.0 License.

Copyright (c) 2025 MHSarmadi