Skip to content

Commit

Permalink
readme
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Nov 3, 2024
1 parent ac7a601 commit c9b06a5
Showing 1 changed file with 34 additions and 26 deletions.
60 changes: 34 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ import { xchacha20poly1305 } from '@noble/ciphers/chacha';

## Examples

> [!NOTE]
> Use different nonce every time `encrypt()` is done.
#### Encrypt with XChaCha20-Poly1305

```js
Expand Down Expand Up @@ -100,8 +103,8 @@ import { utf8ToBytes } from '@noble/ciphers/utils';
import { randomBytes } from '@noble/ciphers/webcrypto';
const key = randomBytes(32);
const nonce = randomBytes(24);
const aes = gcm(key, nonce);
const data = utf8ToBytes('hello, noble');
const aes = gcm(key, nonce);
const ciphertext = aes.encrypt(data);
const data_ = aes.decrypt(ciphertext); // utils.bytesToUtf8(data_) === data
```
Expand All @@ -112,21 +115,22 @@ const data_ = aes.decrypt(ciphertext); // utils.bytesToUtf8(data_) === data
import { gcm, siv, ctr, cfb, cbc, ecb } from '@noble/ciphers/aes';
import { randomBytes } from '@noble/ciphers/webcrypto';
const plaintext = new Uint8Array(32).fill(16);
const key = randomBytes(32); // 24 for AES-192, 16 for AES-128
for (let cipher of [gcm, siv]) {
const stream = cipher(key, randomBytes(12));
const ciphertext_ = stream.encrypt(plaintext);
const plaintext_ = stream.decrypt(ciphertext_);
const key = randomBytes(32); // 24 for AES-192, 16 for AES-128
const nonce = randomBytes(12);
const ciphertext_ = cipher(key, nonce).encrypt(plaintext);
const plaintext_ = cipher(key, nonce).decrypt(ciphertext_);
}
for (const cipher of [ctr, cbc, cbc]) {
const stream = cipher(key, randomBytes(16));
const ciphertext_ = stream.encrypt(plaintext);
const plaintext_ = stream.decrypt(ciphertext_);
for (const cipher of [ctr, cbc, cfb]) {
const key = randomBytes(32); // 24 for AES-192, 16 for AES-128
const nonce = randomBytes(16);
const ciphertext_ = cipher(key, nonce).encrypt(plaintext);
const plaintext_ = cipher(key, nonce).decrypt(ciphertext_);
}
for (const cipher of [ecb]) {
const stream = cipher(key);
const ciphertext_ = stream.encrypt(plaintext);
const plaintext_ = stream.decrypt(ciphertext_);
const key = randomBytes(32); // 24 for AES-192, 16 for AES-128
const ciphertext_ = cipher(key).encrypt(plaintext);
const plaintext_ = cipher(key).decrypt(ciphertext_);
}
```

Expand All @@ -142,14 +146,14 @@ import { gcm, ctr, cbc, randomBytes } from '@noble/ciphers/webcrypto';
const plaintext = new Uint8Array(32).fill(16);
const key = randomBytes(32);
for (const cipher of [gcm]) {
const stream = cipher(key, randomBytes(12));
const ciphertext_ = await stream.encrypt(plaintext);
const plaintext_ = await stream.decrypt(ciphertext_);
const nonce = randomBytes(12);
const ciphertext_ = await cipher(key, nonce).encrypt(plaintext);
const plaintext_ = await cipher(key, nonce).decrypt(ciphertext_);
}
for (const cipher of [ctr, cbc]) {
const stream = cipher(key, randomBytes(16));
const ciphertext_ = await stream.encrypt(plaintext);
const plaintext_ = await stream.decrypt(ciphertext_);
const nonce = randomBytes(16);
const ciphertext_ = await cipher(key, nonce).encrypt(plaintext);
const plaintext_ = await cipher(key, nonce).decrypt(ciphertext_);
}
```

Expand Down Expand Up @@ -378,14 +382,18 @@ of a random function. See [draft-irtf-cfrg-aead-limits](https://datatracker.ietf
For non-deterministic (not ECB) schemes, initialization vector (IV) is mixed to block/key;
and each new round either depends on previous block's key, or on some counter.

- ECB — simple deterministic replacement. Dangerous: always map x to y. See [AES Penguin](https://words.filippo.io/the-ecb-penguin/)
- CBC — key is previous round’s block. Hard to use: need proper padding, also needs MAC
- CTR — counter, allows to create streaming cipher. Requires good IV. Parallelizable. OK, but no MAC
- GCM — modern CTR, parallel, with MAC
- SIV — synthetic initialization vector, nonce-misuse-resistant. Guarantees that, when a nonce is repeated,
the only security loss is that identical plaintexts will produce identical ciphertexts.
- XTS — used in hard drives. Similar to ECB (deterministic), but has `[i][j]`
tweak arguments corresponding to sector i and 16-byte block (part of sector) j. Not authenticated!
- ECB (Electronic Codebook): Deterministic encryption; identical plaintext blocks yield identical ciphertexts. Insecure due to pattern leakage.
See [AES Penguin](https://words.filippo.io/the-ecb-penguin/)
- CBC (Cipher Block Chaining): Each plaintext block is XORed with the previous ciphertext block before encryption.
Hard to use: requires proper padding and an IV. Needs a separate MAC.
- CTR (Counter Mode): Turns a block cipher into a stream cipher using a counter and IV (nonce).
Efficient and parallelizable. Requires a unique nonce per encryption. Better, but still needs a separate MAC.
- GCM (Galois/Counter Mode): Combines CTR mode with polynomial MAC. Efficient and widely used.
- SIV (Synthetic IV): Nonce-misuse-resistant mode; repeating nonces reveal only if plaintexts are identical.
Maintains security even if nonces are reused.
- XTS: Designed for disk encryption.
Similar to ECB (deterministic), but has `[i][j]` tweak arguments corresponding to sector i and 16-byte block (part of sector) j.
Lacks MAC.

GCM / SIV are not ideal:

Expand Down

0 comments on commit c9b06a5

Please sign in to comment.