Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DES

A from-scratch, single-file implementation of the DES block cipher in C99 that prints its round-by-round internal state, wrapped in a small two-block CBC-mode demo.

What it is

This is a personal, educational implementation of the DES (Data Encryption Standard) block cipher, hand-written in C from the standard DES permutation and S-box tables. It exists to inspect how DES transforms a 64-bit block — the core routine prints intermediate state on every round — rather than to serve as a drop-in cryptographic library. Every input is hardcoded; there is no API, command-line interface, or file I/O.

The whole cipher lives in one function, des(uint64_t input, uint64_t key, char mode), in des.c. The rest of the repository is that same code with different main() drivers, kept as .txt files.

Repository layout

  • des.c — the only file the Makefile builds. Contains the DES tables, the des() routine, and a main() that runs a two-block CBC encrypt-then-decrypt demonstration on hardcoded test vectors.
  • Makefile — a gcc / C99 build that compiles des.c into an executable named des.
  • cbc mode.txt — a byte-for-byte copy of des.c (identical SHA-256), kept as a plain-text snapshot; the CBC logic it refers to already lives in des.c.
  • reversible proof.txt — the same tables and the same des() function as des.c (the two files differ only inside main()), with a driver that encrypts one block directly (no CBC) and then decrypts the hardcoded constant 0x3fa40e8a984d4815. Under the sample key that constant is exactly the encryption of the sample plaintext 0x4e6f772069732074, so the decrypt call returns that plaintext, demonstrating that 'd' mode inverts 'e' mode. It is a complete program but is not referenced by the Makefile.
  • main.txt — a main() snippet only: no #includes and no des() definition, so it does not compile on its own. It prints a Round Round Output Round Key header and encrypts a single block; paste it over des.c's main() to get single-block round output instead of the CBC demo.

There is no license file and no test suite in the repository.

How it works

des(uint64_t input, uint64_t key, char mode) implements textbook DES over 64-bit blocks:

  • Initial / final permutation — the input is permuted by IP[] into a 64-bit value that is split into a 32-bit left half L and right half R; after the 16 rounds, PI[] (the inverse permutation) is applied to the pre-output to produce the result.
  • Key schedulePC1[] selects 56 bits of the 64-bit key into two 28-bit halves C and D. For each round, C and D are left-rotated by iteration_shift[] bits (the schedule 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1), and PC2[] compresses the pair into a 48-bit subkey. All sixteen subkeys are precomputed into sub_key[16] before the rounds run.
  • Round (Feistel) function — for each of the 16 rounds the 32-bit right half is expanded to 48 bits with E[], XORed with the round subkey, substituted through the eight S-boxes S[8][64], and permuted with P[]; that result is XORed into the left half (temp = R; R = L ^ f_function_res; L = temp).
  • Encrypt vs. decrypt — the mode argument only changes subkey order: 'd' applies sub_key[15-i] (reverse order); any other value — the code passes 'e' — applies sub_key[i] (forward order). Applying the subkeys in reverse inverts encryption.
  • Diagnostics — every call to des() prints 16 lines to stdout (round numbers 1 through 16), one per round, each line being the round number (%2d), a 64-bit intermediate block (%016llx), and a 48-bit subkey (%012llx). The function then returns the 64-bit result. There is no way to run the cipher without this output.

des.c's main() wraps the cipher in CBC mode: each plaintext block is XORed with the previous ciphertext block (the first with the IV) before encryption, and the chaining is reversed on decryption. The hardcoded inputs are two 64-bit plaintext blocks 0x4e6f772069732074 and 0x6f6d65206d6f7265, key 0x0123456789abcdef, and IV 0xaabbccddeeff0011; running the program decrypts the two ciphertext blocks back to those plaintext values.

Building & running

The Makefile sets CC = gcc and CFLAGS = -Wall -std=c99:

make        # compiles des.c and links the ./des executable
./des       # runs the two-block CBC encrypt/decrypt demo
make clean  # removes des.o and des

The build succeeds but is not warning-clean: under -Wall, gcc emits several -Wparentheses warnings about operator precedence in the key-rotation and S-box index expressions (no errors). The program takes no command-line arguments and does no file I/O — every value is hardcoded in main().

To exercise the other drivers, edit the sources by hand:

  • replace des.c's main() with the snippet in main.txt to get single-block round output; or
  • build reversible proof.txt directly. Because it has a .txt extension you must tell the compiler it is C, for example gcc -x c -std=c99 "reversible proof.txt" -o reversible.

Status & caveats

  • Educational / inspection code, not a library or tool: des() always prints round diagnostics, and every input is hardcoded — no API, CLI, or file I/O.
  • The default build is the two-block CBC demo, not a single-block driver.
  • Operates on whole 64-bit blocks only: no padding, no arbitrary-length message handling, and no key-parity or weak-key checking.
  • The tables are the standard DES tables and the demo round-trips (decrypt inverts encrypt), but the repository contains no known-answer tests against the official DES vectors, so bit-exact standard conformance is not asserted here.
  • Not written to be constant-time or resistant to timing / side-channel attacks.
  • No automated tests and no license file are present in the repository.
  • DES has a 56-bit effective key and is not secure for real-world use; this code is for understanding the algorithm, not for protecting data.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages