Skip to content

Commit

Permalink
Refactor: rename assertions, decrease bundle size
Browse files Browse the repository at this point in the history
  • Loading branch information
paulmillr committed Nov 22, 2024
1 parent 6558eaf commit 2280e7f
Show file tree
Hide file tree
Showing 10 changed files with 37 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/_arx.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.
import { bool as abool, bytes as abytes, number as anumber } from './_assert.js';
import { abool, abytes, anumber } from './_assert.js';
import { XorStream, checkOpts, clean, copyBytes, u32 } from './utils.js';

/*
Expand Down
29 changes: 18 additions & 11 deletions src/_assert.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
function number(n: number) {
function anumber(n: number) {
if (!Number.isSafeInteger(n) || n < 0) throw new Error(`positive integer expected, not ${n}`);
}

function bool(b: boolean) {
function abool(b: boolean) {
if (typeof b !== 'boolean') throw new Error(`boolean expected, not ${b}`);
}

export function isBytes(a: unknown): a is Uint8Array {
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
}

function bytes(b: Uint8Array | undefined, ...lengths: number[]) {
function abytes(b: Uint8Array | undefined, ...lengths: number[]) {
if (!isBytes(b)) throw new Error('Uint8Array expected');
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error(`Uint8Array expected of length ${lengths}, not of length=${b.length}`);
Expand All @@ -22,26 +22,33 @@ export type Hash = {
outputLen: number;
create: any;
};
function hash(hash: Hash) {
function ahash(hash: Hash) {
if (typeof hash !== 'function' || typeof hash.create !== 'function')
throw new Error('hash must be wrapped by utils.wrapConstructor');
number(hash.outputLen);
number(hash.blockLen);
anumber(hash.outputLen);
anumber(hash.blockLen);
}

function exists(instance: any, checkFinished = true) {
function aexists(instance: any, checkFinished = true) {
if (instance.destroyed) throw new Error('Hash instance has been destroyed');
if (checkFinished && instance.finished) throw new Error('Hash#digest() has already been called');
}

function output(out: any, instance: any) {
bytes(out);
function aoutput(out: any, instance: any) {
abytes(out);
const min = instance.outputLen;
if (out.length < min) {
throw new Error(`digestInto() expects output buffer of length at least ${min}`);
}
}

export { number, bool, bytes, hash, exists, output };
const assert = { number, bool, bytes, hash, exists, output };
export { anumber, abool, abytes, ahash, aexists, aoutput };
const assert = {
number: anumber,
bool: abool,
bytes: abytes,
hash: ahash,
exists: aexists,
output: aoutput,
};
export default assert;
2 changes: 1 addition & 1 deletion src/_micro.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
// prettier-ignore
import { createCipher, rotl } from './_arx.js';
import { bytes as abytes } from './_assert.js';
import { abytes } from './_assert.js';
import {
Cipher,
XorStream,
Expand Down
2 changes: 1 addition & 1 deletion src/_poly1305.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bytes as abytes, exists as aexists, output as aoutput } from './_assert.js';
import { abytes, aexists, aoutput } from './_assert.js';
import { Hash, Input, clean, toBytes } from './utils.js';

// Poly1305 is a fast and parallel secret-key message-authentication code.
Expand Down
2 changes: 1 addition & 1 deletion src/_polyval.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { bytes as abytes, exists as aexists, output as aoutput } from './_assert.js';
import { abytes, aexists, aoutput } from './_assert.js';
import { clean, copyBytes, createView, Hash, Input, toBytes, u32 } from './utils.js';

// GHash from AES-GCM and its little-endian "mirror image" Polyval from AES-SIV.
Expand Down
14 changes: 7 additions & 7 deletions src/aes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// prettier-ignore
import { bytes as abytes } from './_assert.js';
import { abytes } from './_assert.js';
import { ghash, polyval } from './_polyval.js';
import {
Cipher,
Expand Down Expand Up @@ -325,7 +325,7 @@ function ctr32(
*/
export const ctr = wrapCipher(
{ blockSize: 16, nonceLength: 16 },
function ctr(key: Uint8Array, nonce: Uint8Array): CipherWithOutput {
function aesctr(key: Uint8Array, nonce: Uint8Array): CipherWithOutput {
function processCtr(buf: Uint8Array, dst?: Uint8Array) {
abytes(buf);
if (dst !== undefined) {
Expand Down Expand Up @@ -403,7 +403,7 @@ export type BlockOpts = { disablePadding?: boolean };
*/
export const ecb = wrapCipher(
{ blockSize: 16 },
function ecb(key: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {
function aesecb(key: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {
const pcks5 = !opts.disablePadding;
return {
encrypt(plaintext: Uint8Array, dst?: Uint8Array) {
Expand Down Expand Up @@ -447,7 +447,7 @@ export const ecb = wrapCipher(
*/
export const cbc = wrapCipher(
{ blockSize: 16, nonceLength: 16 },
function cbc(key: Uint8Array, iv: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {
function aescbc(key: Uint8Array, iv: Uint8Array, opts: BlockOpts = {}): CipherWithOutput {
const pcks5 = !opts.disablePadding;
return {
encrypt(plaintext: Uint8Array, dst?: Uint8Array) {
Expand Down Expand Up @@ -507,7 +507,7 @@ export const cbc = wrapCipher(
*/
export const cfb = wrapCipher(
{ blockSize: 16, nonceLength: 16 },
function cfb(key: Uint8Array, iv: Uint8Array): CipherWithOutput {
function aescfb(key: Uint8Array, iv: Uint8Array): CipherWithOutput {
function processCfb(src: Uint8Array, isEncrypt: boolean, dst?: Uint8Array) {
abytes(src);
const srcLen = src.length;
Expand Down Expand Up @@ -580,7 +580,7 @@ function computeTag(
*/
export const gcm = wrapCipher(
{ blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },
function gcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {
function aesgcm(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {
// NIST 800-38d doesn't enforce minimum nonce length.
// We enforce 8 bytes for compat with openssl.
// 12 bytes are recommended. More than 12 bytes would be converted into 12.
Expand Down Expand Up @@ -654,7 +654,7 @@ const limit = (name: string, min: number, max: number) => (value: number) => {
*/
export const siv = wrapCipher(
{ blockSize: 16, nonceLength: 12, tagLength: 16, varSizeNonce: true },
function siv(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {
function aessiv(key: Uint8Array, nonce: Uint8Array, AAD?: Uint8Array): Cipher {
const tagLength = 16;
// From RFC 8452: Section 6
const AAD_LIMIT = limit('AAD', 0, 2 ** 36);
Expand Down
2 changes: 1 addition & 1 deletion src/ff1.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { number as anumber, bytes as abytes } from './_assert.js';
import { anumber, abytes } from './_assert.js';
import { unsafe } from './aes.js';
import { Cipher, bytesToNumberBE, clean, numberToBytesBE } from './utils.js';
// NOTE: no point in inlining encrypt instead of encryptBlock, since BigInt stuff will be slow
Expand Down
2 changes: 1 addition & 1 deletion src/salsa.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createCipher, rotl } from './_arx.js';
import { bytes as abytes } from './_assert.js';
import { abytes } from './_assert.js';
import { poly1305 } from './_poly1305.js';
import { Cipher, clean, equalBytes, getDst, wrapCipher } from './utils.js';

Expand Down
2 changes: 1 addition & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */
import { bytes as abytes, isBytes } from './_assert.js';
import { abytes, isBytes } from './_assert.js';
// prettier-ignore
export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array |
Uint16Array | Int16Array | Uint32Array | Int32Array;
Expand Down
10 changes: 5 additions & 5 deletions src/webcrypto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
// Use full path so that Node.js can rewrite it to `cryptoNode.js`.
import { crypto } from '@noble/ciphers/crypto';
import { bytes as abytes, number } from './_assert.js';
import { abytes, anumber } from './_assert.js';
import { AsyncCipher, Cipher, concatBytes } from './utils.js';

/**
Expand Down Expand Up @@ -44,7 +44,7 @@ type CipherWithNonce = ((key: Uint8Array, nonce: Uint8Array, ...args: any[]) =>

// Uses CSPRG for nonce, nonce injected in ciphertext
export function managedNonce<T extends CipherWithNonce>(fn: T): RemoveNonce<T> {
number(fn.nonceLength);
anumber(fn.nonceLength);
return ((key: Uint8Array, ...args: any[]): any => ({
encrypt(plaintext: Uint8Array, ...argsEnc: any[]) {
const { nonceLength } = fn;
Expand Down Expand Up @@ -120,9 +120,9 @@ function generate(algo: BlockMode) {
};
}

export const cbc = generate(mode.CBC);
export const ctr = generate(mode.CTR);
export const gcm = generate(mode.GCM);
export const cbc = /* @__PURE__ */ (() => generate(mode.CBC))();
export const ctr = /* @__PURE__ */ (() => generate(mode.CTR))();
export const gcm = /* @__PURE__ */ (() => generate(mode.GCM))();

// // Type tests
// import { siv, gcm, ctr, ecb, cbc } from '../aes.js';
Expand Down

0 comments on commit 2280e7f

Please sign in to comment.