Skip to content

Commit

Permalink
Rename xchacha20_poly1305 to xchacha20poly1305 (and others)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Jul 18, 2023
1 parent 2139e8d commit 664e9fd
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 54 deletions.
45 changes: 23 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ If you don't like NPM, a standalone
```js
// import * from '@noble/ciphers'; // Error
// Use sub-imports for tree-shaking, to ensure small size of your apps
import { xsalsa20_poly1305 } from '@noble/ciphers/salsa';
import { xsalsa20poly1305 } from '@noble/ciphers/salsa';
import { utf8ToBytes } from '@noble/ciphers/utils';
import { randomBytes } from '@noble/ciphers/webcrypto/utils';

Expand All @@ -51,20 +51,20 @@ const nonce = randomBytes(24);
const data = utf8ToBytes('hello, noble'); // strings must be converted to Uint8Array

// XSalsa20
const stream_s = xsalsa20_poly1305(key, nonce);
const stream_s = xsalsa20poly1305(key, nonce);
const encrypted_s = stream_s.encrypt(data);
stream_s.decrypt(encrypted_s); // === data

// XChaCha
import { xchacha20_poly1305 } from '@noble/ciphers/salsa';
const stream_xc = xchacha20_poly1305(key, nonce);
import { xchacha20poly1305 } from '@noble/ciphers/salsa';
const stream_xc = xchacha20poly1305(key, nonce);
const encrypted_xc = stream_xc.encrypt(data);
stream_xc.decrypt(encrypted_xc); // === data

// ChaCha
import { chacha20_poly1305 } from '@noble/ciphers/chacha';
import { chacha20poly1305 } from '@noble/ciphers/chacha';
const nonce12 = randomBytes(12);
const stream_c = chacha20_poly1305(key, nonce12);
const stream_c = chacha20poly1305(key, nonce12);
const encrypted_c = stream_c.encrypt(data);
stream_c.decrypt(encrypted_c); // === data
```
Expand Down Expand Up @@ -151,19 +151,20 @@ of a random function. See [RFC draft](https://datatracker.ietf.org/doc/draft-irt
### Salsa

```js
import { xsalsa20_poly1305, secretbox } from '@noble/ciphers/salsa';
import { xsalsa20poly1305 } from '@noble/ciphers/salsa';
import { utf8ToBytes } from '@noble/ciphers/utils';
import { randomBytes } from '@noble/ciphers/webcrypto/utils';

const key = randomBytes(32);
const data = utf8ToBytes('hello, noble'); // strings must be converted to Uint8Array

const nonce = randomBytes(24);
const stream_x = xsalsa20_poly1305(key, nonce); // === secretbox(key, nonce)
const stream_x = xsalsa20poly1305(key, nonce); // === secretbox(key, nonce)
const ciphertext = stream_x.encrypt(data); // === secretbox.seal(data)
const plaintext = stream_x.decrypt(ciphertext); // === secretbox.open(ciphertext)

// We provide sodium secretbox alias, which is just xsalsa20_poly1305
// We provide sodium secretbox alias, which is just xsalsa20poly1305
import { secretbox } from '@noble/ciphers/salsa';
const box = secretbox(key, nonce);
const ciphertext = box.seal(plaintext);
const plaintext = box.open(ciphertext);
Expand Down Expand Up @@ -194,20 +195,20 @@ alias and corresponding seal / open methods.
### ChaCha

```js
import { chacha20_poly1305, xchacha20_poly1305 } from '@noble/ciphers/chacha';
import { chacha20poly1305, xchacha20poly1305 } from '@noble/ciphers/chacha';
import { utf8ToBytes } from '@noble/ciphers/utils';
import { randomBytes } from '@noble/ciphers/webcrypto/utils';

const key = randomBytes(32);
const data = utf8ToBytes('hello, noble'); // strings must be converted to Uint8Array

const nonce12 = randomBytes(12); // chacha uses 96-bit nonce
const stream_c = chacha20_poly1305(key, nonce12);
const stream_c = chacha20poly1305(key, nonce12);
const ciphertext_c = stream_c.encrypt(data);
const plaintext_c = stream_c.decrypt(ciphertext_c); // === data

const nonce24 = randomBytes(24); // xchacha uses 192-bit nonce
const stream_xc = xchacha20_poly1305(key, nonce24);
const stream_xc = xchacha20poly1305(key, nonce24);
const ciphertext_xc = stream_xc.encrypt(data);
const plaintext_xc = stream_xc.decrypt(ciphertext_xc); // === data

Expand Down Expand Up @@ -332,20 +333,20 @@ Benchmark results on Apple M2 with node v20:

```
encrypt (64B)
├─xsalsa20_poly1305 x 484,966 ops/sec @ 2μs/op
├─chacha20_poly1305 x 442,282 ops/sec @ 2μs/op
├─xsalsa20poly1305 x 484,966 ops/sec @ 2μs/op
├─chacha20poly1305 x 442,282 ops/sec @ 2μs/op
└─xchacha20poly1305 x 300,842 ops/sec @ 3μs/op
encrypt (1KB)
├─xsalsa20_poly1305 x 143,905 ops/sec @ 6μs/op
├─chacha20_poly1305 x 141,663 ops/sec @ 7μs/op
├─xsalsa20poly1305 x 143,905 ops/sec @ 6μs/op
├─chacha20poly1305 x 141,663 ops/sec @ 7μs/op
└─xchacha20poly1305 x 122,639 ops/sec @ 8μs/op
encrypt (8KB)
├─xsalsa20_poly1305 x 23,373 ops/sec @ 42μs/op
├─chacha20_poly1305 x 23,683 ops/sec @ 42μs/op
├─xsalsa20poly1305 x 23,373 ops/sec @ 42μs/op
├─chacha20poly1305 x 23,683 ops/sec @ 42μs/op
└─xchacha20poly1305 x 23,066 ops/sec @ 43μs/op
encrypt (1MB)
├─xsalsa20_poly1305 x 193 ops/sec @ 5ms/op
├─chacha20_poly1305 x 196 ops/sec @ 5ms/op
├─xsalsa20poly1305 x 193 ops/sec @ 5ms/op
├─chacha20poly1305 x 196 ops/sec @ 5ms/op
└─xchacha20poly1305 x 195 ops/sec @ 5ms/op
```

Expand Down Expand Up @@ -377,12 +378,12 @@ encrypt (1MB)
Compare to other implementations:

```
xsalsa20_poly1305 (encrypt, 1MB)
xsalsa20poly1305 (encrypt, 1MB)
├─tweetnacl x 108 ops/sec @ 9ms/op
├─noble x 190 ops/sec @ 5ms/op
└─micro x 21 ops/sec @ 47ms/op
chacha20_poly1305 (encrypt, 1MB)
chacha20poly1305 (encrypt, 1MB)
├─node x 1,360 ops/sec @ 735μs/op
├─stablelib x 117 ops/sec @ 8ms/op
├─noble x 193 ops/sec @ 5ms/op
Expand Down
12 changes: 6 additions & 6 deletions benchmark/aead.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { compare, utils as butils } from 'micro-bmark';
import { createCipheriv, createDecipheriv } from 'node:crypto';

import { concatBytes } from '@noble/ciphers/utils';
import { xchacha20_poly1305, chacha20_poly1305 } from '@noble/ciphers/chacha';
import { xsalsa20_poly1305 } from '@noble/ciphers/salsa';
import { xchacha20poly1305 as xchacha20_poly1305, chacha20poly1305 as chacha20_poly1305 } from '@noble/ciphers/chacha';
import { xsalsa20poly1305 as xsalsa20_poly1305 } from '@noble/ciphers/salsa';
import * as micro from '@noble/ciphers/_micro';

import { ChaCha20Poly1305 as StableChachaPoly } from '@stablelib/chacha20poly1305';
Expand Down Expand Up @@ -82,8 +82,8 @@ export const CIPHERS = {
decrypt: (buf, opts) => chacha20_poly1305(opts.key, opts.nonce).decrypt(buf),
},
micro: {
encrypt: (buf, opts) => micro.chacha20_poly1305(opts.key, opts.nonce).encrypt(buf),
decrypt: (buf, opts) => micro.chacha20_poly1305(opts.key, opts.nonce).decrypt(buf),
encrypt: (buf, opts) => micro.chacha20poly1305(opts.key, opts.nonce).encrypt(buf),
decrypt: (buf, opts) => micro.chacha20poly1305(opts.key, opts.nonce).decrypt(buf),
},
},
xchacha20poly1305: {
Expand All @@ -97,8 +97,8 @@ export const CIPHERS = {
decrypt: (buf, opts) => xchacha20_poly1305(opts.key, opts.nonce).decrypt(buf),
},
micro: {
encrypt: (buf, opts) => micro.xchacha20_poly1305(opts.key, opts.nonce).encrypt(buf),
decrypt: (buf, opts) => micro.xchacha20_poly1305(opts.key, opts.nonce).decrypt(buf),
encrypt: (buf, opts) => micro.xchacha20poly1305(opts.key, opts.nonce).encrypt(buf),
decrypt: (buf, opts) => micro.xchacha20poly1305(opts.key, opts.nonce).decrypt(buf),
},
},
};
Expand Down
11 changes: 6 additions & 5 deletions benchmark/cross_test.test.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { deepStrictEqual, throws } from 'assert';
import { should, describe } from 'micro-should';
import { CIPHERS } from './index.js';
import { CIPHERS } from './aead.js';

describe('Big', () => {
should('secretbox', () => {
const big4g = new Uint8Array(2 ** 32 - 32).fill(7);
const big4g = new Uint8Array(2 ** 32 - 32).fill(7); // 4GB - 32b
const libs = CIPHERS.xsalsa20_poly1305;
const nacl4 = libs.tweetnacl.encrypt(big4g, libs.opts);
const noble4 = libs.noble.encrypt(big4g, libs.opts);
const { opts } = libs;
const nacl4 = libs.tweetnacl.encrypt(big4g, opts);
const noble4 = libs.noble.encrypt(big4g, opts);
deepStrictEqual(noble4, nacl4, 'noble encrypt');
deepStrictEqual(libs.noble.decrypt(noble4, libs.opts), big4g, 'noble decrypt');
deepStrictEqual(libs.noble.decrypt(noble4, opts), big4g, 'noble decrypt');
});
});

Expand Down
8 changes: 4 additions & 4 deletions src/_micro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ function computeTag(
/**
* xsalsa20-poly1305 eXtended-nonce (24 bytes) salsa.
*/
export function xsalsa20_poly1305(key: Uint8Array, nonce: Uint8Array) {
export function xsalsa20poly1305(key: Uint8Array, nonce: Uint8Array) {
u.ensureBytes(key);
u.ensureBytes(nonce);
return {
Expand Down Expand Up @@ -269,7 +269,7 @@ export function xsalsa20_poly1305(key: Uint8Array, nonce: Uint8Array) {
export function secretbox(key: Uint8Array, nonce: Uint8Array) {
u.ensureBytes(key);
u.ensureBytes(nonce);
const xs = xsalsa20_poly1305(key, nonce);
const xs = xsalsa20poly1305(key, nonce);
return { seal: xs.encrypt, open: xs.decrypt };
}

Expand Down Expand Up @@ -304,10 +304,10 @@ export const _poly1305_aead =
/**
* chacha20-poly1305 12-byte-nonce chacha.
*/
export const chacha20_poly1305 = _poly1305_aead(chacha20);
export const chacha20poly1305 = _poly1305_aead(chacha20);

/**
* xchacha20-poly1305 eXtended-nonce (24 bytes) chacha.
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
*/
export const xchacha20_poly1305 = _poly1305_aead(xchacha20);
export const xchacha20poly1305 = _poly1305_aead(xchacha20);
4 changes: 2 additions & 2 deletions src/chacha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,10 @@ export const _poly1305_aead =
* ChaCha20-Poly1305 from RFC 8439.
* With 12-byte nonce, it's not safe to use fill it with random (CSPRNG), due to collision chance.
*/
export const chacha20_poly1305 = _poly1305_aead(chacha20);
export const chacha20poly1305 = _poly1305_aead(chacha20);
/**
* XChaCha20-Poly1305 extended-nonce chacha.
* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
*/
export const xchacha20_poly1305 = _poly1305_aead(xchacha20);
export const xchacha20poly1305 = _poly1305_aead(xchacha20);
4 changes: 2 additions & 2 deletions src/salsa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export const xsalsa20 = salsaBasic({
* With 24-byte nonce, it's safe to use fill it with random (CSPRNG).
* Also known as secretbox from libsodium / nacl.
*/
export const xsalsa20_poly1305 = (key: Uint8Array, nonce: Uint8Array): Cipher => {
export const xsalsa20poly1305 = (key: Uint8Array, nonce: Uint8Array): Cipher => {
const tagLength = 16;
ensureBytes(key, 32);
ensureBytes(nonce, 24);
Expand Down Expand Up @@ -168,6 +168,6 @@ export const xsalsa20_poly1305 = (key: Uint8Array, nonce: Uint8Array): Cipher =>
export function secretbox(key: Uint8Array, nonce: Uint8Array) {
ensureBytes(key);
ensureBytes(nonce);
const xs = xsalsa20_poly1305(key, nonce);
const xs = xsalsa20poly1305(key, nonce);
return { seal: xs.encrypt, open: xs.decrypt };
}
26 changes: 13 additions & 13 deletions test/basic.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const { deepStrictEqual, throws } = require('assert');
const { should, describe } = require('micro-should');
const { hex, base64 } = require('@scure/base');
const { salsa20, hsalsa, xsalsa20, xsalsa20_poly1305 } = require('../salsa.js');
const { salsa20, hsalsa, xsalsa20, xsalsa20poly1305 } = require('../salsa.js');
const {
chacha20,
chacha20orig,
hchacha,
xchacha20,
chacha20_poly1305,
xchacha20_poly1305,
chacha20poly1305,
xchacha20poly1305,
} = require('../chacha.js');
const { poly1305 } = require('../_poly1305.js');
const slow = require('../_micro.js');
Expand Down Expand Up @@ -216,17 +216,17 @@ describe('poly1305', () => {
}
});
};
t('Chacha20Poly1305', stable_chacha_poly, chacha20_poly1305);
t('Xchacha20Poly1305', stable_xchacha_poly, xchacha20_poly1305);
t('Chacha20Poly1305', stable_chacha_poly, slow.chacha20_poly1305);
t('Xchacha20Poly1305', stable_xchacha_poly, slow.xchacha20_poly1305);
t('Chacha20Poly1305', stable_chacha_poly, chacha20poly1305);
t('Xchacha20Poly1305', stable_xchacha_poly, xchacha20poly1305);
t('Chacha20Poly1305', stable_chacha_poly, slow.chacha20poly1305);
t('Xchacha20Poly1305', stable_xchacha_poly, slow.xchacha20poly1305);
});

should('tweetnacl secretbox compat', () => {
for (let i = 0; i < tweetnacl_secretbox.length; i++) {
const v = tweetnacl_secretbox[i];
const [key, nonce, msg, exp] = v.map(base64.decode);
const c = xsalsa20_poly1305(key, nonce);
const c = xsalsa20poly1305(key, nonce);
deepStrictEqual(hex.encode(c.encrypt(msg)), hex.encode(exp), i);
deepStrictEqual(hex.encode(c.decrypt(exp)), hex.encode(msg), i);
const cSlow = slow.xsalsa20_poly1305(key, nonce);
Expand All @@ -240,7 +240,7 @@ should('handle byte offsets correctly', () => {
const data = new Uint8Array(sample.buffer, 1);
const key = new Uint8Array(32).fill(2);
const nonce12 = new Uint8Array(12).fill(3);
const stream_c = chacha20_poly1305(key, nonce12);
const stream_c = chacha20poly1305(key, nonce12);
const encrypted_c = stream_c.encrypt(data);
stream_c.decrypt(encrypted_c); // === data
});
Expand Down Expand Up @@ -271,10 +271,10 @@ describe('Wycheproof', () => {
}
});
};
t('wycheproof_chacha20_poly1305', wycheproof_chacha20_poly1305, chacha20_poly1305);
t('wycheproof_xchacha20_poly1305', wycheproof_xchacha20_poly1305, xchacha20_poly1305);
t('wycheproof_chacha20_poly1305', wycheproof_chacha20_poly1305, slow.chacha20_poly1305);
t('wycheproof_xchacha20_poly1305', wycheproof_xchacha20_poly1305, slow.xchacha20_poly1305);
t('wycheproof_chacha20_poly1305', wycheproof_chacha20_poly1305, chacha20poly1305);
t('wycheproof_xchacha20_poly1305', wycheproof_xchacha20_poly1305, xchacha20poly1305);
t('wycheproof_chacha20_poly1305', wycheproof_chacha20_poly1305, slow.chacha20poly1305);
t('wycheproof_xchacha20_poly1305', wycheproof_xchacha20_poly1305, slow.xchacha20poly1305);
});

if (require.main === module) should.run();

0 comments on commit 664e9fd

Please sign in to comment.