| Crates.io | paks |
| lib.rs | paks |
| version | 0.1.1 |
| created_at | 2025-09-02 20:02:16.984515+00 |
| updated_at | 2025-09-23 20:23:32.853607+00 |
| description | A light-weight encrypted archive inspired by the Quake PAK format. |
| homepage | |
| repository | https://github.com/CasualX/paks |
| max_upload_size | |
| id | 1821591 |
| size | 144,220 |
The PAKS file is a lightweight encrypted archive inspired by the Quake PAK format.
This library implements a "Bring Your Own Authenticated Encryption" scheme using Speck128/128 in CTR mode with a CBC-MAC.
Disclaimer: This is not a production-grade cryptosystem. It's designed for obfuscation and integrity checking of game assets in hobby projects. Think of it as experimental and fun, use at your own risk.
This project ships with pakscmd, a command-line utility for creating and editing PAKS files.
cargo install paks
This installs pakscmd for manipulating archives:
pakscmd by Casper - Copyright (c) 2020-2025 Casper <CasualX@users.noreply.github.com>
USAGE
pakscmd help <COMMAND>
pakscmd <PAKFILE> <KEY> <COMMAND> [..]
ARGUMENTS
PAKFILE Path to a PAKS archive to create or edit.
KEY The 128-bit encryption key encoded in hex.
COMMAND The subcommand to invoke.
Commands are:
new Creates a new empty PAKS archive.
tree Displays the directory of the PAKS archive.
add Adds a file to the PAKS archive.
copy Copies files to the PAKS archive.
link Links the file from alternative paths.
cat Reads files from the PAKS archive and writes to stdout.
rm Removes paths from the PAKS archive.
mv Moves files in the PAKS archive.
gc Collects garbage left behind by removed files.
See `pakscmd help <COMMAND>` for more information on a specific command.
EXAMPLES
pakscmd example.paks 0 new
pakscmd example.paks 0 add a/b/example < tests/data/example.txt
pakscmd example.paks 0 link a/b/example aa/bb/example
pakscmd example.paks 0 tree -u
pakscmd example.paks 0 rm a/b/example
pakscmd example.paks 0 cat aa/bb/example
Here's how to create a new PAKS file and add some content:
Try it locally with: cargo run --example readme1.
// This file contains 65 bytes filled with `0xCF`.
const DATA: &[u8] = &[0xCF; 65];
fn main() {
let ref key = [13, 42];
// Create the editor object to create PAKS files in memory.
let mut edit = paks::MemoryEditor::new();
// Let's create a file `foo` under a directory `sub`.
// If a file already exists by this name it will be overwritten.
edit.create_file(b"sub/foo", DATA, key);
// When done the editor object can be finalized and returns the encrypted PAKS file as a `Vec<Block>`.
// It also returns the unencrypted directory for final inspection if desired.
let (paks, dir) = edit.finish(key);
// Print the directory.
print!("The directory:\n\n```\n{}```\n\n", dir.display());
// Print the PAKS file itself.
print!("The RAW data:\n\n```\n{:x?}\n```\n", paks);
// Create the reader object to inspect PAKS files in memory.
let read = paks::MemoryReader::from_blocks(paks, key).unwrap();
// Find the file created earlier and read its data into a `Vec<u8>`.
let data = read.read(b"sub/foo", key).unwrap();
// Check that it still matches the expected data.
assert_eq!(DATA, &data[..]);
}
The structure of a PAKS archive is straightforward:
Header — contains the version number and directory location.
Data — opaque blocks of file contents, decryptable only using directory information.
Directory — a sequence of descriptors in a lightweight TLV format.
+-------------------+
| Header | --> Contains version + pointer to Directory
+-------------------+
| |
| File A |
| | --> Data: Encrypted sections (opaque blocks)
| File B |
| |
+-------------------+
| Directory | --> List of descriptors:
| +-----------+ |
| | File A | --+----> File descriptors: Metadata + pointer to Data
| +-----------+ |
| | File B | --+----> File descriptors: Includes nonce + MAC for integrity
| +-----------+ |
| | Dir/.. | --+----> Directory descriptors: Define hierarchy
| +-----------+ |
+-------------------+
Licensed under MIT License, see license.txt.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, shall be licensed as above, without any additional terms or conditions.