Skip to content

Securely search encrypted documents. Encrypts and decrypts text and binary files > 32 bytes.

License

Notifications You must be signed in to change notification settings

xiaolin-ninja/fencrypt_search

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

32 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Encrypted File Search

The fencrypt program implements encrypted search for text and binary files greater than 32 bytes. Supports all unicode characters.

This program also encrypts and decrypts files using a four-round feistel cipher, and supports encrypted search and ciphertext tamper detection with HMAC-SHA-256.

Usage

Encrypt:

fencrypt -e <file_name>

Decrypt:

fencrypt -d <file_name>

Search:

fencrypt -s "string"

Search supports word prefix:

fencrypt -s string*

❯ ./fencrypt -h
usage: fencrypt [-h] [-d] [-e] [-s] [-v] inputs [inputs ...]

Encrypts and decrypts binary and text files. Plaintext search on encrypted files.

positional arguments:
  inputs      file path or search string

optional arguments:
  -h, --help  show this help message and exit
  -d          decrypt
  -e          encrypt
  -s          search
  -v          verbose output to terminal

Example

❯ make clean all

# https://www.gutenberg.org/ebooks/2264
curl -s https://www.gutenberg.org/cache/epub/2264/pg2264.txt | tee macbeth.txt.plain > macbeth.txt
encrypting with password: 'macbeth.txt'
echo -n macbeth.txt | ./fencrypt -e -v macbeth.txt
{
    "macbeth.txt": "4241a8f0f9711be7ef8df0f78280c827dd95bbe1c15983f98194e5bc365707e2"
}

# https://www.gutenberg.org/ebooks/17996
curl -s https://www.gutenberg.org/files/17996/17996-0.txt | tee aeschylus.txt.plain > aeschylus.txt
encrypting with password: 'aeschylus.txt'
echo -n aeschylus.txt | ./fencrypt -e -v aeschylus.txt
{
    "aeschylus.txt": "a8aded8f6c715ae675f9cfc5fea5bd2a902284fa2f4732c2b001e425bf7082c8"
}

# https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
curl -s https://upload.wikimedia.org/wikipedia/commons/f/f0/Tux_ecb.jpg | tee ecb.jpg.plain > ecb.jpg
encrypting with password: 'ecb.jpg'
echo -n ecb.jpg | ./fencrypt -e -v ecb.jpg
{
    "ecb.jpg": "4140d3287a64918b56c80de058936c047b2f86c72021d4be95e7471a97fbc7d1"
}

echo -n wrongpassword | ./fencrypt -s crickets

echo -n macbeth.txt | ./fencrypt -s haha

echo -n macbeth.txt | ./fencrypt -s -v crickets
Incorrect password for file .fenc-meta.aeschylus.txt.
Incorrect password for file .fenc-meta.ecb.jpg.
{
    "macbeth.txt": "4241a8f0f9711be7ef8df0f78280c827dd95bbe1c15983f98194e5bc365707e2"
}
macbeth.txt

echo -n macbeth.txt | ./fencrypt -s cric*
macbeth.txt

echo -n aeschylus.txt | ./fencrypt -s άδραστου
aeschylus.txt

echo -n aeschylus.txt | ./fencrypt -s άδρασ*
aeschylus.txt

Under the Hood

Architecture Diagram

ascii art πŸ˜€
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
       β”‚                  plaintext                  β”‚
       β”‚                (any length)                 │──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  only if plaintext is text, not binary                                                                                           β”‚
                              β”‚                                                                                                                                                         β”‚
                              β”‚                                                                                                                                                         β”‚
                 first        β”‚          rest                                                                                                                                           β”‚
                 16 bytes     β”‚         bytes                                                                                                                                           β”‚
               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                                                                                                                         β”‚
               β”‚                              β”‚                                                                                                                                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚AES-CTR round β”‚                              β”‚                β”‚              β”‚Master Key                                               β”‚               β”‚indexing text                                                    β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚                                                         β”‚               β”‚                                                                 β”‚
β”‚              β–Ό                              β–Ό                β”‚              β”‚                                                         β”‚               β”‚             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚              β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚               β”‚             β”‚                                  β”‚                β”‚
β”‚      β”‚     left     β”‚               β”‚    right     β”‚         β”‚              β”‚      β”‚   password   β”‚           β”‚     salt     β”‚        β”‚               β”‚             β”‚          extract words           β”‚                β”‚
β”‚      β”‚  (16 bytes)  β”‚               β”‚ (rest bytes) β”‚         β”‚              β”‚      β”‚ (any length) β”‚           β”‚  (16 bytes)  │────────────────┐       β”‚             β”‚     (4-12 code points long)      β”‚                β”‚
β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚              β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚       β”‚       β”‚             β”‚                                  β”‚                β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β”‚                          β”‚               β”‚       β”‚       β”‚             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β–Ό                          β–Ό               β”‚       β”‚       β”‚                               β”‚                                 β”‚
β”‚              β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”                     β”‚                β”‚              β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”‚       β”‚       β”‚             β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”‚
β”‚              β”‚     16 β”‚                     β”‚                β”‚              β”‚      β”‚           PBKDF2-HMAC-SHA256            β”‚        β”‚       β”‚       β”‚             β”‚                                  β”‚                β”‚
β”‚              β”‚        β”‚                     β”‚                β”‚              β”‚      β”‚          (250,000 iterations)           β”‚        β”‚       β”‚       β”‚             β–Ό                                  β–Ό                β”‚
β”‚              β”‚        β–Ό                     β”‚                β”‚              β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚       β”‚       β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  16   β”‚                β”‚              β”‚                           β”‚                             β”‚       β”‚       β”‚     β”‚     word     β”‚        ...        β”‚     word     β”‚         β”‚
β”‚              β”‚    β”‚  iv        key  │◀──────────────────────────────────┐   β”‚                           β–Ό                             β”‚       β”‚       β”‚     β”‚              β”‚                   β”‚              β”‚         β”‚
β”‚              β”‚    β”‚     AES-CTR     β”‚       β”‚                β”‚          β”‚   β”‚                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                      β”‚       β”‚       β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚                β”‚          β”‚   β”‚                   β”‚  master key  β”‚                      β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚             β”‚                β–Ό                β”‚          β”‚   β”‚                   β”‚  (32 bytes)  β”‚                      β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚             β”‚keystream     β”Œβ”€β”€β”€β”              β”‚          β”‚   β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚             └─────────────▢│xorβ”‚              β”‚          β”‚   β”‚                           β”‚                             β”‚       β”‚       β”‚            β–Ό                                   β–Ό                β”‚
β”‚              β”‚                            β””β”€β”€β”€β”˜              β”‚          β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚       β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚              β”‚                              β”‚                β”‚          β”‚                               β”‚                                     β”‚       β”‚     β”‚                                                 β”‚         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚       β”‚     β”‚    for each word, generate star search terms    β”‚         β”‚
               β”‚                              β”‚                           β”‚   β”‚Key Schedule               β”‚                             β”‚       β”‚       β”‚     β”‚    (add start between 4-12 code-points)         β”‚         β”‚
               β”‚                              β”‚                           β”‚   β”‚              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”              β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚     β”‚    for "building":                              β”‚         β”‚
β”‚HMAC round    β”‚                              β”‚                β”‚          β”‚   β”‚              β”‚ first 16        second 16 β”‚              β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
β”‚              β”‚                              β”‚                β”‚          β”‚   β”‚              β–Ό bytes               bytes β–Ό              β”‚       β”‚       β”‚     β”‚    * building                                   β”‚         β”‚
β”‚              β–Ό                              β–Ό                β”‚          β”‚   β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚       β”‚       β”‚     β”‚    * buildin*                                   β”‚         β”‚
β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚          β”‚   β”‚      β”‚ schedule key β”‚            β”‚ schedule iv  β”‚       β”‚       β”‚       β”‚     β”‚    * buildi*                                    β”‚         β”‚
β”‚      β”‚     left     β”‚               β”‚    right     β”‚         β”‚          β”‚   β”‚      β”‚  (16 bytes)  β”‚            β”‚  (16 bytes)  β”‚       β”‚       β”‚       β”‚     β”‚    * build*                                     β”‚         β”‚
β”‚      β”‚  (16 bytes)  β”‚               β”‚ (rest bytes) β”‚         β”‚          β”‚   β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚       β”‚       β”‚     β”‚    * buil*                                      β”‚         β”‚
β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚          β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
β”‚              β”‚                              β”‚                β”‚          β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚              β”‚                              β”‚                β”‚          β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚                              β”‚                β”‚          β”‚   β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚   β”‚              β”œβ”€β”€β”€β–Άβ”‚  key        iv  │◀────              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚              16 β”‚            β”‚                β”‚       β”‚  β”‚   β”‚              β”‚    β”‚    AES block    β”‚    β”‚              β”‚       β”‚       β”‚            β–Ό                                   β–Ό                β”‚
β”‚              β”‚                 β–Ό            β”‚                β”‚       β”‚  β”‚   β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚              β”‚       β”‚       β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚              β”‚        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚                β”‚       β”‚  β”‚   β”‚              β”‚             β”‚             β”‚              β”‚       β”‚       β”‚    β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”                  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”       β”‚
β”‚              β”‚        β”‚       key       β”‚   β”‚                β”‚       β”‚  β”‚   β”‚              β”‚             β–Ό             β”‚              β”‚       β”‚       β”‚    β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”     ...        β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”     β”‚
β”‚              β”‚        β”‚   HMAC-SHA256   │◀───                β”‚       β”‚  β”‚   β”‚              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚              β”‚       β”‚       β”‚    └── β”‚    search    β”‚                └── β”‚    search    β”‚     β”‚
β”‚              β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚                β”‚       β”‚  β”‚   β”‚              β”‚     β”‚   validator   β”‚     β”‚              β”‚       β”‚       β”‚      └──     term     β”‚                  └──     term     β”‚     β”‚
β”‚              β–Ό                 β”‚            β”‚                β”‚       β”‚  β”‚   β”‚              β”‚     β”‚  (16 bytes)   │────────────────────────────│       β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚            β”Œβ”€β”€β”€β”               β”‚            β”‚                β”‚       β”‚  β”‚   β”‚              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚            β”‚xorβ”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ MAC        β”‚                β”‚       β”‚  β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚            β””β”€β”€β”€β”˜    (first 16 bytes)        β”‚                β”‚       β”‚  β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚            β–Ό                                   β–Ό                β”‚
β”‚              β”‚                              β”‚                β”‚       β”‚  β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚              β”‚                              β”‚                β”‚       β”‚  β”‚   β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +1 β”‚              β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚  β”‚   β”‚              β”œβ”€β”€β”€β–Άβ”‚  key        iv  │◀────              β”‚       β”‚       β”‚     β”‚    casefold and normalize all search terms      β”‚         β”‚
               β”‚                              β”‚                        β”‚  β”‚   β”‚              β”‚    β”‚    AES block    β”‚    β”‚              β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
               β”‚                              β”‚                        β”‚  β”‚   β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚              β”‚       β”‚       β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚  β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚AES-CTR round β”‚                              β”‚                β”‚       β”‚  β”‚   β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚                              β”‚                β”‚       β”‚  β”‚   β”‚              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚              β”‚       β”‚       β”‚            β–Ό                                   β–Ό                β”‚
β”‚              β–Ό                              β–Ό                β”‚       β”‚  β”‚   β”‚              β”‚     β”‚   feistel 1   β”‚     β”‚              β”‚       β”‚       β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚       β”‚  └────────────────────────│  (16 bytes)   β”‚     β”‚              β”‚       β”‚       β”‚    β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”                  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”       β”‚
β”‚      β”‚     left     β”‚               β”‚    right     β”‚         β”‚       β”‚      β”‚              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚              β”‚       β”‚       β”‚    β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”     ...        β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”     β”‚
β”‚      β”‚  (16 bytes)  β”‚               β”‚ (rest bytes) β”‚         β”‚       β”‚      β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚    └── β”‚    search    β”‚                └── β”‚    search    β”‚     β”‚
β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚       β”‚      β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚      └──     term     β”‚                  └──     term     β”‚     β”‚
β”‚              β”‚                              β”‚                β”‚       β”‚      β”‚              β”‚                           β”‚              β”‚       β”‚       β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”‚              β”‚                              β”‚                β”‚       β”‚      β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +2 β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”                     β”‚                β”‚       β”‚      β”‚              β”œβ”€β”€β”€β–Άβ”‚  key        iv  │◀────              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚     16 β”‚                     β”‚                β”‚       β”‚      β”‚              β”‚    β”‚    AES block    β”‚    β”‚              β”‚       β”‚       β”‚            β”‚                                   β”‚                β”‚
β”‚              β”‚        β”‚                     β”‚                β”‚       β”‚      β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚              β”‚       β”‚       β”‚            β–Ό                                   β–Ό                β”‚
β”‚              β”‚        β–Ό                     β”‚                β”‚       β”‚      β”‚              β”‚             β”‚             β”‚              β”‚       β”‚       β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  16   β”‚                β”‚       β”‚      β”‚              β”‚             β–Ό             β”‚              β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
β”‚              β”‚    β”‚  iv        key  │◀────────────────────────────┐  β”‚      β”‚              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”‚          HMAC-SHA256 all search terms           β”‚         β”‚
β”‚              β”‚    β”‚     AES-CTR     β”‚       β”‚                β”‚    β”‚  β”‚      β”‚              β”‚     β”‚   feistel 2   β”‚     β”‚       β”‚      β”‚       β”‚       β”‚     β”‚                                                 β”‚         β”‚
β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚                β”‚    β”‚  └───────────────────────────│  (16 bytes)   β”‚     β”‚       β”‚      β”‚       β”‚       β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚              β”‚             β”‚                β–Ό                β”‚    β”‚         β”‚              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚       β”‚      β”‚       β”‚       β”‚                              β”‚                                  β”‚
β”‚              β”‚             β”‚keystream     β”Œβ”€β”€β”€β”              β”‚    β”‚         β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚       β”‚                              β”‚                                  β”‚
β”‚              β”‚             └─────────────▢│xorβ”‚              β”‚    β”‚         β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚       β”‚                              β”‚                                  β”‚
β”‚              β”‚                            β””β”€β”€β”€β”˜              β”‚    β”‚         β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚       β”‚                              β–Ό                                  β”‚
β”‚              β”‚                              β”‚                β”‚    β”‚         β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +3 β”‚       β”‚      β”‚       β”‚       β”‚                      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚         β”‚              β”œβ”€β”€β”€β–Άβ”‚  key        iv  │◀────       β”‚      β”‚       β”‚       β”‚                      β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”                         β”‚
               β”‚                              β”‚                     β”‚         β”‚              β”‚    β”‚    AES block    β”‚    β”‚       β”‚      β”‚       β”‚       β”‚                      β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”                       β”‚
               β”‚                              β”‚                     β”‚         β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚       β”‚      β”‚       β”‚       β”‚                      └── β”‚     mac      β”‚                       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚         β”‚              β”‚             β”‚             β”‚       β”‚      β”‚       β”‚       β”‚                        └──              β”‚                       β”‚
β”‚HMAC round    β”‚                              β”‚                β”‚    β”‚         β”‚              β”‚             β–Ό             β”‚       β”‚      β”‚       β”‚       β”‚                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚              β”‚                              β”‚                β”‚    β”‚         β”‚              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚       β”‚      β”‚       β”‚       β”‚                                  β”‚                              β”‚
β”‚              β–Ό                              β–Ό                β”‚    β”‚         β”‚              β”‚     β”‚   feistel 3   β”‚     β”‚       β”‚      β”‚       β”‚       β”‚                                  β”‚                              β”‚
β”‚      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚    └──────────────────────────────│  (16 bytes)   β”‚     β”‚       β”‚      β”‚       β”‚       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚      β”‚     left     β”‚               β”‚    right     β”‚         β”‚              β”‚              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚      β”‚  (16 bytes)  β”‚               β”‚ (rest bytes) β”‚         β”‚              β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                 each 32  β”‚
β”‚      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚              β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                   bytes  β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +4 β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β”œβ”€β”€β”€β–Άβ”‚  key        iv  │◀────       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚                 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚              β”‚    β”‚    AES block    β”‚    β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚              16 β”‚            β”‚                β”‚    β”‚         β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚                 β–Ό            β”‚                β”‚    β”‚         β”‚              β”‚             β”‚             β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚                β”‚    β”‚         β”‚              β”‚             β–Ό             β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚        β”‚       key       β”‚   β”‚                β”‚    β”‚         β”‚              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚        β”‚   HMAC-SHA256   │◀──│                β”‚    β”‚         β”‚              β”‚     β”‚   feistel 4   β”‚     β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚                β”‚    └──────────────────────────────│  (16 bytes)   β”‚     β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β–Ό                 β”‚            β”‚                β”‚              β”‚              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚            β”Œβ”€β”€β”€β”               β”‚            β”‚                β”‚              β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚            β”‚xorβ”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ MAC        β”‚                β”‚              β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚            β””β”€β”€β”€β”˜    (first 16 bytes)        β”‚                β”‚              β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +5 β”‚       β”‚      β”‚       β”‚                                          β”‚
β”‚              β”‚                              β”‚                β”‚              β”‚              β”œβ”€β”€β”€β–Άβ”‚  key        iv  │◀────       β”‚      β”‚       β”‚                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜              β”‚              β”‚    β”‚    AES block    β”‚    β”‚       β”‚      β”‚       β”‚                                          β”‚
               β”‚                              β”‚                               β”‚              β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚       β”‚      β”‚       β”‚                                          β”‚
               β”‚                              β”‚                               β”‚              β”‚             β”‚             β”‚       β”‚      β”‚       β”‚                                          β”‚
               β”‚                              β”‚                               β”‚              β”‚             β–Ό             β”‚       β”‚      β”‚       β”‚                                          β”‚
               β”‚      concatenate bytes       β”‚                               β”‚              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚       β”‚      β”‚       β”‚                                          β”‚
               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β”‚              β”‚     β”‚      mac      β”‚     β”‚       β”‚      β”‚       β”‚                                          β”‚
                              β”‚                                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”‚  (16 bytes)   β”‚     β”‚       β”‚      β”‚       β”‚                                          β”‚
                              β–Ό                                         β”‚     β”‚              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚       β”‚      β”‚       β”‚                                          β”‚
       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚     β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
       β”‚                 ciphertext                  β”‚                  β”‚     β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
       β”‚         (same length as plaintext)          β”‚                  β”‚     β”‚              β”‚                           β”‚       β”‚      β”‚       β”‚                                          β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚     β”‚              β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +6 β”‚       β”‚      β”‚       β”‚                                          β”‚
                              β”‚                                         β”‚     β”‚              └───▢│ key        iv+6 β”‚β—€β”€β”€β”€β”˜       β”‚      β”‚       β”‚                                          β”‚
                              β”‚                                         β”‚     β”‚                   β”‚    AES block    β”‚            β”‚      β”‚       β”‚                                          β”‚
                              β–Ό                                         β”‚     β”‚                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β”‚      β”‚       β”‚                                          β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                         β”‚     β”‚                            β”‚                     β”‚      β”‚       β”‚                                          β”‚
              β”‚          HMAC-SHA256          β”‚                         β”‚     β”‚                            β–Ό                     β”‚      β”‚       β”‚                                          β”‚
              β”‚                               β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚      β”‚       β”‚                                          β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β”‚                    β”‚    search     β”‚             β”‚      β”‚       β”‚                                          β”‚
                              β”‚                                               β”‚                    β”‚  (16 bytes)   β”‚β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β”‚       β”‚                                          β”‚
                              β”‚                                               β”‚                    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚       β”‚                                          β”‚
                              β”‚                                               β”‚                                                         β”‚       β”‚                                          β”‚
                              β”‚                                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚                                          β”‚
                              β”‚                                                                                                                 β”‚                                          β”‚
                              β”‚  mac                                                                                                            β”‚                                          β”‚
                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                                                                                                β”‚
                                                                                                                                                β–Ό
                                                                                                                                        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                                                                                                                        β”‚   metadata   β”‚
                                                                                                                                        β”‚     file     β”‚
                                                                                                                                        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
png

Encryption Diagram

Summary

When encrypting, a 32-byte "master" key is generated from a user-supplied password for each file encrypted, using PBKDF2 with HMAC-SHA-256 as the PRF.

The 16-byte salt is randomly generated from a secure random number generator, and stored in the per-file metadata.

A series of 16-byte keys are generated using counter mode:

  • AES(Master_key, IV) : a password validator (see below).
  • AES(Master_key, IV + 1) : the first round key in the Feistel Cipher
  • AES(Master_key, IV + 2) : the second round key in the Feistel Cipher
  • AES(Master_key, IV + 3) : the third round key in the Feistel Cipher
  • AES(Master_key, IV + 4) : the fourth round key in the Feistel Cipher
  • AES(Master_key, IV + 5) : the MAC key.
  • AES(Master_key, IV + 6) : the key used for encrypting search terms.

The plaintext file is then encrypted using a four-round feistel cipher, alternating AES CTR mode and HMAC rounds.

UTF-8 encoded text files are indexed for search terms upon encryption. Search terms are any contiguous sequence of Unicode letters (character classes Lu, Ll, Lt, Lm, Lo), non-spacing marks (class Mn), decimel digits (Nd) and connector punctuation (Pc) between 4-12 codepoints. Search terms are casefolded, normalized, then MAC'd using HMAC-SHA-256.

The salt, validator, mac, and hashed search terms are stored in a per-file generated metadata. The password and hash are validated upon decryption.

Note:

This program is my final project for the "Applied Cryptography" course in the New York University Masters of Science in Cybersecurity program, Spring 2022.

About

Securely search encrypted documents. Encrypts and decrypts text and binary files > 32 bytes.

Resources

License

Stars

Watchers

Forks