https://github.com/soatok/experimental-caead
Experimental committing AEAD designed by Soatok.
https://github.com/soatok/experimental-caead
cryptography
Last synced: 10 months ago
JSON representation
Experimental committing AEAD designed by Soatok.
- Host: GitHub
- URL: https://github.com/soatok/experimental-caead
- Owner: soatok
- Created: 2020-09-09T09:49:28.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2020-09-10T07:36:32.000Z (almost 6 years ago)
- Last Synced: 2025-08-16T03:23:25.578Z (10 months ago)
- Topics: cryptography
- Language: JavaScript
- Homepage: https://soatok.blog/2020/09/09/designing-new-cryptography-for-non-standard-threat-models
- Size: 26.4 KB
- Stars: 10
- Watchers: 3
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# cAEAD - Committing AEAD
Committing AEAD with ChaCha20 and BLAKE3.
> **Warning:** This is an experiment created by Soatok for fun. **Don't use it.**
>
> 
#### Make sure you [read the blog post that accompanies this repository](https://soatok.blog/2020/09/09/designing-new-cryptography-for-non-standard-threat-models/).
## What does this do?
This implements an [RKR-secure](https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/)
alternative to XChaCha20-Poly1305, for use in protocols that require RKR security (i.e. OPAQUE).
The primitives used (ChaCha20, BLAKE3) are secure and constant-time in software.
Although large nonces (32 bytes) are employed by this construction, it is not strictly speaking nonce misuse resistant.
If you reuse a `(nonce, key)` tuple with two different messages, attackers will learn the XOR of the two plaintexts.
(We're using the IETF variant of ChaCha20 with 96-bit nonces and 32-bit counters.)
## How to Test this Code
```
git clone https://github.com/soatok/experimental-caead
cd js
npm install
npm test
```
## Algorithm Definition
## Notation
| Symbol | Meaning |
|--------|---------|
| `:=` | Assignment (store right-side value in left-side variable) |
| || | Concatenation |
| `var[x:y]` | Slice `var` from index `x` to `y` |
### Constants
Algorithm prefix: `CRYPTO_CAEAD_CHACHA20BLAKE3_`
```
DOMAIN_ENCRYPT := "Soatok01"
DOMAIN_AUTH := "Soatok}~"
NONCE_BYTES := 32
KEY_BYTES := 32
TAG_BYTES := 32
```
### Encryption Algorithm
1. Split the key into an encryption key and an authentication key.
```
encKey := BLAKE3.keyedHash(key, DOMAIN_ENCRYPT || nonce[0:19])
authKey := BLAKE3.keyedHash(key, DOMAIN_AUTH || nonce[0:19])
```
2. Encrypt the message:
```
C := ChaCha20.encrypt(plaintext, nonce[20:31], encKey, block_counter = 0)
```
3. Calculate the authentication tag:
```
T := BLAKE3.keyedHash(authKey, aad || C || STORE64LE(aad.length) || STORE64LE(C.length))
```
4. Return `T || C`
### Decryption Algorithm
1. Split the key into an encryption key and an authentication key.
```
encKey := BLAKE3.keyedHash(key, DOMAIN_ENCRYPT || nonce[0:19])
authKey := BLAKE3.keyedHash(key, DOMAIN_AUTH || nonce[0:19])
```
2. Realculate the authentication tag:
```
T' := BLAKE3.keyedHash(authKey, aad || C || STORE64LE(aad.length) || STORE64LE(C.length))
```
3. Compare T with T' in constant-time. If it fails, abort.
4. Decrypt the message:
```
P := ChaCha20.decrypt(C, nonce[20:31], encKey, block_counter = 0)
```
5. Return the decrypted plaintext.