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

Commit e37ffaf

Browse files
committed
Heap & asm pooling
1 parent 7cfab68 commit e37ffaf

File tree

5 files changed

+80
-34
lines changed

5 files changed

+80
-34
lines changed

src/aes/aes.ts

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { AES_asm, AES_mode } from './aes.asm';
22
import { _heap_init, _heap_write, is_bytes } from '../other/utils';
33
import { IllegalArgumentError, SecurityError } from '../other/errors';
44

5+
const heap_pool = [];
6+
const asm_pool = [];
7+
58
export abstract class AES {
69
protected readonly heap: Uint8Array;
710
protected readonly asm: AES_asm;
@@ -13,14 +16,34 @@ export abstract class AES {
1316
protected constructor(key: Uint8Array, iv: Uint8Array | undefined, padding = true, mode: AES_mode) {
1417
this.mode = mode;
1518

16-
// The AES "worker"
17-
this.heap = _heap_init().subarray(AES_asm.HEAP_DATA);
18-
this.asm = new AES_asm(null, this.heap.buffer);
19-
2019
// The AES object state
2120
this.pos = 0;
2221
this.len = 0;
2322

23+
this.key = key;
24+
this.iv = iv;
25+
this.padding = padding;
26+
27+
// The AES "worker"
28+
this.acquire_asm();
29+
}
30+
31+
protected acquire_asm() {
32+
if (this.heap === undefined && this.asm === undefined) {
33+
this.heap = heap_pool.pop() || _heap_init().subarray(AES_asm.HEAP_DATA);
34+
this.asm = asm_pool.pop() || AES_asm(null, this.heap.buffer);
35+
this.reset(this.key, this.iv);
36+
}
37+
}
38+
39+
protected release_asm() {
40+
heap_pool.push(this.heap));
41+
asm_pool.push(this.asm);
42+
this.heap = undefined;
43+
this.asm = undefined;
44+
}
45+
46+
protected reset(key, iv) {
2447
// Key
2548
const keylen = key.length;
2649
if (keylen !== 16 && keylen !== 24 && keylen !== 32) throw new IllegalArgumentError('illegal key size');
@@ -48,13 +71,13 @@ export abstract class AES {
4871
} else {
4972
this.asm.set_iv(0, 0, 0, 0);
5073
}
51-
52-
this.padding = padding;
5374
}
5475

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

79+
this.acquire_asm();
80+
5881
let asm = this.asm;
5982
let heap = this.heap;
6083
let amode = AES_asm.ENC[this.mode];
@@ -96,6 +119,8 @@ export abstract class AES {
96119
}
97120

98121
AES_Encrypt_finish(): Uint8Array {
122+
this.acquire_asm();
123+
99124
let asm = this.asm;
100125
let heap = this.heap;
101126
let amode = AES_asm.ENC[this.mode];
@@ -128,12 +153,16 @@ export abstract class AES {
128153
this.pos = 0;
129154
this.len = 0;
130155

156+
this.release_asm();
157+
131158
return result;
132159
}
133160

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

164+
this.acquire_asm();
165+
137166
let asm = this.asm;
138167
let heap = this.heap;
139168
let amode = AES_asm.DEC[this.mode];
@@ -181,6 +210,8 @@ export abstract class AES {
181210
}
182211

183212
AES_Decrypt_finish(): Uint8Array {
213+
this.acquire_asm();
214+
184215
let asm = this.asm;
185216
let heap = this.heap;
186217
let amode = AES_asm.DEC[this.mode];
@@ -221,6 +252,8 @@ export abstract class AES {
221252
this.pos = 0;
222253
this.len = 0;
223254

255+
this.release_asm();
256+
224257
return result;
225258
}
226259
}

src/hash/hash.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { _heap_write } from '../other/utils';
1+
import { _heap_init, _heap_write } from '../other/utils';
22
import { IllegalStateError } from '../other/errors';
33
import { sha1result } from './sha1/sha1.asm';
44
import { sha256result } from './sha256/sha256.asm';
@@ -13,7 +13,32 @@ export abstract class Hash<T extends sha1result | sha256result | sha512result> {
1313
public BLOCK_SIZE!: number;
1414
public HASH_SIZE!: number;
1515

16+
protected static heap_pool !: Array;
17+
protected static asm_pool !: Array;
18+
protected static asm_function!: Function;
19+
20+
constructor() {
21+
this.acquire_asm();
22+
}
23+
24+
protected acquire_asm() {
25+
if (this.heap === undefined && this.asm === undefined) {
26+
this.heap = this.constructor.heap_pool.pop() || _heap_init();
27+
this.asm = this.constructor.asm_pool.pop() || this.constructor.asm_function({ Uint8Array: Uint8Array }, null, this.heap.buffer);
28+
this.reset();
29+
}
30+
}
31+
32+
protected release_asm() {
33+
this.constructor.heap_pool.push(this.heap));
34+
this.constructor.asm_pool.push(this.asm);
35+
this.heap = undefined;
36+
this.asm = undefined;
37+
}
38+
1639
reset() {
40+
this.acquire_asm();
41+
1742
this.result = null;
1843
this.pos = 0;
1944
this.len = 0;
@@ -26,6 +51,8 @@ export abstract class Hash<T extends sha1result | sha256result | sha512result> {
2651
process(data: Uint8Array) {
2752
if (this.result !== null) throw new IllegalStateError('state must be reset before processing new data');
2853

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

87+
this.acquire_asm();
88+
6089
this.asm.finish(this.pos, this.len, 0);
6190

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

97+
this.release_asm();
98+
6899
return this;
69100
}
70101
}

src/hash/sha1/sha1.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { sha1_asm, sha1result } from './sha1.asm';
22
import { Hash } from '../hash';
3-
import { _heap_init } from '../../other/utils';
43

54
export const _sha1_block_size = 64;
65
export const _sha1_hash_size = 20;
@@ -11,12 +10,7 @@ export class Sha1 extends Hash<sha1result> {
1110
public BLOCK_SIZE = _sha1_block_size;
1211
public HASH_SIZE = _sha1_hash_size;
1312

14-
constructor() {
15-
super();
16-
17-
this.heap = _heap_init();
18-
this.asm = sha1_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
19-
20-
this.reset();
21-
}
13+
protected static heap_pool = [];
14+
protected static asm_pool = [];
15+
protected static asm_function = sha1_asm;
2216
}

src/hash/sha256/sha256.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { sha256_asm, sha256result } from './sha256.asm';
22
import { Hash } from '../hash';
3-
import { _heap_init } from '../../other/utils';
43

54
export const _sha256_block_size = 64;
65
export const _sha256_hash_size = 32;
@@ -11,12 +10,7 @@ export class Sha256 extends Hash<sha256result> {
1110
public BLOCK_SIZE = _sha256_block_size;
1211
public HASH_SIZE = _sha256_hash_size;
1312

14-
constructor() {
15-
super();
16-
17-
this.heap = _heap_init();
18-
this.asm = sha256_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
19-
20-
this.reset();
21-
}
13+
protected static heap_pool = [];
14+
protected static asm_pool = [];
15+
protected static asm_function = sha256_asm;
2216
}

src/hash/sha512/sha512.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { sha512_asm, sha512result } from './sha512.asm';
22
import { Hash } from '../hash';
3-
import { _heap_init } from '../../other/utils';
43

54
export const _sha512_block_size = 128;
65
export const _sha512_hash_size = 64;
@@ -11,12 +10,7 @@ export class Sha512 extends Hash<sha512result> {
1110
public BLOCK_SIZE = _sha512_block_size;
1211
public HASH_SIZE = _sha512_hash_size;
1312

14-
constructor() {
15-
super();
16-
17-
this.heap = _heap_init();
18-
this.asm = sha512_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
19-
20-
this.reset();
21-
}
13+
protected static heap_pool = [];
14+
protected static asm_pool = [];
15+
protected static asm_function = sha512_asm;
2216
}

0 commit comments

Comments
 (0)