Skip to content
This repository has been archived by the owner on Feb 7, 2023. It is now read-only.

Commit

Permalink
Heap & asm pooling
Browse files Browse the repository at this point in the history
  • Loading branch information
twiss committed Jul 30, 2018
1 parent 7cfab68 commit e37ffaf
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 34 deletions.
45 changes: 39 additions & 6 deletions src/aes/aes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { AES_asm, AES_mode } from './aes.asm';
import { _heap_init, _heap_write, is_bytes } from '../other/utils';
import { IllegalArgumentError, SecurityError } from '../other/errors';

const heap_pool = [];
const asm_pool = [];

export abstract class AES {
protected readonly heap: Uint8Array;
protected readonly asm: AES_asm;
Expand All @@ -13,14 +16,34 @@ export abstract class AES {
protected constructor(key: Uint8Array, iv: Uint8Array | undefined, padding = true, mode: AES_mode) {
this.mode = mode;

// The AES "worker"
this.heap = _heap_init().subarray(AES_asm.HEAP_DATA);
this.asm = new AES_asm(null, this.heap.buffer);

// The AES object state
this.pos = 0;
this.len = 0;

this.key = key;
this.iv = iv;
this.padding = padding;

// The AES "worker"
this.acquire_asm();
}

protected acquire_asm() {
if (this.heap === undefined && this.asm === undefined) {
this.heap = heap_pool.pop() || _heap_init().subarray(AES_asm.HEAP_DATA);
this.asm = asm_pool.pop() || AES_asm(null, this.heap.buffer);
this.reset(this.key, this.iv);
}
}

protected release_asm() {
heap_pool.push(this.heap));
asm_pool.push(this.asm);
this.heap = undefined;
this.asm = undefined;
}

protected reset(key, iv) {
// Key
const keylen = key.length;
if (keylen !== 16 && keylen !== 24 && keylen !== 32) throw new IllegalArgumentError('illegal key size');
Expand Down Expand Up @@ -48,13 +71,13 @@ export abstract class AES {
} else {
this.asm.set_iv(0, 0, 0, 0);
}

this.padding = padding;
}

AES_Encrypt_process(data: Uint8Array): Uint8Array {
if (!is_bytes(data)) throw new TypeError("data isn't of expected type");

this.acquire_asm();

let asm = this.asm;
let heap = this.heap;
let amode = AES_asm.ENC[this.mode];
Expand Down Expand Up @@ -96,6 +119,8 @@ export abstract class AES {
}

AES_Encrypt_finish(): Uint8Array {
this.acquire_asm();

let asm = this.asm;
let heap = this.heap;
let amode = AES_asm.ENC[this.mode];
Expand Down Expand Up @@ -128,12 +153,16 @@ export abstract class AES {
this.pos = 0;
this.len = 0;

this.release_asm();

return result;
}

AES_Decrypt_process(data: Uint8Array): Uint8Array {
if (!is_bytes(data)) throw new TypeError("data isn't of expected type");

this.acquire_asm();

let asm = this.asm;
let heap = this.heap;
let amode = AES_asm.DEC[this.mode];
Expand Down Expand Up @@ -181,6 +210,8 @@ export abstract class AES {
}

AES_Decrypt_finish(): Uint8Array {
this.acquire_asm();

let asm = this.asm;
let heap = this.heap;
let amode = AES_asm.DEC[this.mode];
Expand Down Expand Up @@ -221,6 +252,8 @@ export abstract class AES {
this.pos = 0;
this.len = 0;

this.release_asm();

return result;
}
}
33 changes: 32 additions & 1 deletion src/hash/hash.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { _heap_write } from '../other/utils';
import { _heap_init, _heap_write } from '../other/utils';
import { IllegalStateError } from '../other/errors';
import { sha1result } from './sha1/sha1.asm';
import { sha256result } from './sha256/sha256.asm';
Expand All @@ -13,7 +13,32 @@ export abstract class Hash<T extends sha1result | sha256result | sha512result> {
public BLOCK_SIZE!: number;
public HASH_SIZE!: number;

protected static heap_pool !: Array;
protected static asm_pool !: Array;
protected static asm_function!: Function;

constructor() {
this.acquire_asm();
}

protected acquire_asm() {
if (this.heap === undefined && this.asm === undefined) {
this.heap = this.constructor.heap_pool.pop() || _heap_init();
this.asm = this.constructor.asm_pool.pop() || this.constructor.asm_function({ Uint8Array: Uint8Array }, null, this.heap.buffer);
this.reset();
}
}

protected release_asm() {
this.constructor.heap_pool.push(this.heap));
this.constructor.asm_pool.push(this.asm);
this.heap = undefined;
this.asm = undefined;
}

reset() {
this.acquire_asm();

this.result = null;
this.pos = 0;
this.len = 0;
Expand All @@ -26,6 +51,8 @@ export abstract class Hash<T extends sha1result | sha256result | sha512result> {
process(data: Uint8Array) {
if (this.result !== null) throw new IllegalStateError('state must be reset before processing new data');

this.acquire_asm();

let asm = this.asm;
let heap = this.heap;
let hpos = this.pos;
Expand Down Expand Up @@ -57,6 +84,8 @@ export abstract class Hash<T extends sha1result | sha256result | sha512result> {
finish() {
if (this.result !== null) throw new IllegalStateError('state must be reset before processing new data');

this.acquire_asm();

this.asm.finish(this.pos, this.len, 0);

this.result = new Uint8Array(this.HASH_SIZE);
Expand All @@ -65,6 +94,8 @@ export abstract class Hash<T extends sha1result | sha256result | sha512result> {
this.pos = 0;
this.len = 0;

this.release_asm();

return this;
}
}
12 changes: 3 additions & 9 deletions src/hash/sha1/sha1.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { sha1_asm, sha1result } from './sha1.asm';
import { Hash } from '../hash';
import { _heap_init } from '../../other/utils';

export const _sha1_block_size = 64;
export const _sha1_hash_size = 20;
Expand All @@ -11,12 +10,7 @@ export class Sha1 extends Hash<sha1result> {
public BLOCK_SIZE = _sha1_block_size;
public HASH_SIZE = _sha1_hash_size;

constructor() {
super();

this.heap = _heap_init();
this.asm = sha1_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);

this.reset();
}
protected static heap_pool = [];
protected static asm_pool = [];
protected static asm_function = sha1_asm;
}
12 changes: 3 additions & 9 deletions src/hash/sha256/sha256.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { sha256_asm, sha256result } from './sha256.asm';
import { Hash } from '../hash';
import { _heap_init } from '../../other/utils';

export const _sha256_block_size = 64;
export const _sha256_hash_size = 32;
Expand All @@ -11,12 +10,7 @@ export class Sha256 extends Hash<sha256result> {
public BLOCK_SIZE = _sha256_block_size;
public HASH_SIZE = _sha256_hash_size;

constructor() {
super();

this.heap = _heap_init();
this.asm = sha256_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);

this.reset();
}
protected static heap_pool = [];
protected static asm_pool = [];
protected static asm_function = sha256_asm;
}
12 changes: 3 additions & 9 deletions src/hash/sha512/sha512.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { sha512_asm, sha512result } from './sha512.asm';
import { Hash } from '../hash';
import { _heap_init } from '../../other/utils';

export const _sha512_block_size = 128;
export const _sha512_hash_size = 64;
Expand All @@ -11,12 +10,7 @@ export class Sha512 extends Hash<sha512result> {
public BLOCK_SIZE = _sha512_block_size;
public HASH_SIZE = _sha512_hash_size;

constructor() {
super();

this.heap = _heap_init();
this.asm = sha512_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);

this.reset();
}
protected static heap_pool = [];
protected static asm_pool = [];
protected static asm_function = sha512_asm;
}

0 comments on commit e37ffaf

Please sign in to comment.