From 39411798c279ee4cd44c802a7fc05a506341161d Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 5 Aug 2024 18:18:39 -0400 Subject: [PATCH 1/5] feat: use allocUnsafe to allocate hash digests --- packages/as-sha256/package.json | 3 +++ packages/as-sha256/src/index.ts | 33 ++++++++++++++++++++++++--------- yarn.lock | 14 +++++++++++++- 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/packages/as-sha256/package.json b/packages/as-sha256/package.json index fc628275..1ac85c9c 100644 --- a/packages/as-sha256/package.json +++ b/packages/as-sha256/package.json @@ -49,5 +49,8 @@ "@chainsafe/babel-plugin-inline-binary-import": "^1.0.3", "assemblyscript": "^0.27.24", "benchmark": "^2.1.4" + }, + "dependencies": { + "uint8arrays": "^5.1.0" } } diff --git a/packages/as-sha256/src/index.ts b/packages/as-sha256/src/index.ts index 867aec60..82c70073 100644 --- a/packages/as-sha256/src/index.ts +++ b/packages/as-sha256/src/index.ts @@ -1,3 +1,4 @@ +import {allocUnsafe} from "uint8arrays/alloc"; import {newInstance} from "./wasm"; import {HashObject, byteArrayToHashObject, hashObjectToByteArray} from "./hashObject"; import SHA256 from "./sha256"; @@ -18,7 +19,7 @@ export function digest(data: Uint8Array): Uint8Array { if (data.length <= ctx.INPUT_LENGTH) { inputUint8Array.set(data); ctx.digest(data.length); - return outputUint8Array.slice(0, 32); + return allocDigest(); } ctx.init(); @@ -30,7 +31,7 @@ export function digest64(data: Uint8Array): Uint8Array { if (data.length === 64) { inputUint8Array.set(data); ctx.digest64(wasmInputValue, wasmOutputValue); - return outputUint8Array.slice(0, 32); + return allocDigest(); } throw new Error("InvalidLengthForDigest64"); } @@ -40,7 +41,7 @@ export function digest2Bytes32(bytes1: Uint8Array, bytes2: Uint8Array): Uint8Arr inputUint8Array.set(bytes1); inputUint8Array.set(bytes2, 32); ctx.digest64(wasmInputValue, wasmOutputValue); - return outputUint8Array.slice(0, 32); + return allocDigest(); } throw new Error("InvalidLengthForDigest64"); } @@ -105,10 +106,10 @@ export function batchHash4UintArray64s(inputs: Uint8Array[]): Uint8Array[] { ctx.batchHash4UintArray64s(wasmOutputValue); - const output0 = outputUint8Array.slice(0, 32); - const output1 = outputUint8Array.slice(32, 64); - const output2 = outputUint8Array.slice(64, 96); - const output3 = outputUint8Array.slice(96, 128); + const output0 = allocDigest(); + const output1 = allocDigestOffset(32); + const output2 = allocDigestOffset(64); + const output3 = allocDigestOffset(96); return [output0, output1, output2, output3]; } @@ -239,7 +240,7 @@ function update(data: Uint8Array): void { const INPUT_LENGTH = ctx.INPUT_LENGTH; if (data.length > INPUT_LENGTH) { for (let i = 0; i < data.length; i += INPUT_LENGTH) { - const sliced = data.slice(i, i + INPUT_LENGTH); + const sliced = data.subarray(i, i + INPUT_LENGTH); inputUint8Array.set(sliced); ctx.update(wasmInputValue, sliced.length); } @@ -251,5 +252,19 @@ function update(data: Uint8Array): void { function final(): Uint8Array { ctx.final(wasmOutputValue); - return outputUint8Array.slice(0, 32); + return allocDigest(); +} + +/** allocate memory and copy result */ +function allocDigest(): Uint8Array { + const out = allocUnsafe(32); + out.set(outputUint8Array); + return out; +} + +/** allocate memory and copy result at offset */ +function allocDigestOffset(offset: number): Uint8Array { + const out = allocUnsafe(32); + out.set(outputUint8Array, offset); + return out; } diff --git a/yarn.lock b/yarn.lock index c22a5dd5..8719305b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2282,7 +2282,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^17", "@types/react@^17.0", "@types/react@^17.0.35": +"@types/react@*", "@types/react@^17", "@types/react@^17.0.35": version "17.0.80" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.80.tgz#a5dfc351d6a41257eb592d73d3a85d3b7dbcbb41" integrity sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA== @@ -8597,6 +8597,11 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" +multiformats@^13.0.0: + version "13.2.2" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.2.2.tgz#16da153ee8b68d8c9da31b52176e90b3cd8b43ef" + integrity sha512-RWI+nyf0q64vyOxL8LbKtjJMki0sogRL/8axvklNtiTM0iFCVtHwME9w6+0P1/v4dQvsIg8A45oT3ka1t/M/+A== + multimatch@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" @@ -11968,6 +11973,13 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== +uint8arrays@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-5.1.0.tgz#14047c9bdf825d025b7391299436e5e50e7270f1" + integrity sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww== + dependencies: + multiformats "^13.0.0" + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" From 03fcfa6236423c10d37d131042e02d811c129f80 Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 5 Aug 2024 18:40:53 -0400 Subject: [PATCH 2/5] chore: remove dependencies --- packages/as-sha256/package.json | 4 +--- packages/as-sha256/src/alloc.ts | 22 ++++++++++++++++++++++ packages/as-sha256/src/index.ts | 8 +++++--- yarn.lock | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 packages/as-sha256/src/alloc.ts diff --git a/packages/as-sha256/package.json b/packages/as-sha256/package.json index 1ac85c9c..1f0cb8d8 100644 --- a/packages/as-sha256/package.json +++ b/packages/as-sha256/package.json @@ -50,7 +50,5 @@ "assemblyscript": "^0.27.24", "benchmark": "^2.1.4" }, - "dependencies": { - "uint8arrays": "^5.1.0" - } + "dependencies": {} } diff --git a/packages/as-sha256/src/alloc.ts b/packages/as-sha256/src/alloc.ts new file mode 100644 index 00000000..87618932 --- /dev/null +++ b/packages/as-sha256/src/alloc.ts @@ -0,0 +1,22 @@ +const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null; + +export const allocUnsafe = isNode ? _allocUnsafeNode : _allocUnsafe; + +/** + * Where possible returns a Uint8Array of the requested size that references + * uninitialized memory. Only use if you are certain you will immediately + * overwrite every value in the returned `Uint8Array`. + */ +function _allocUnsafe(size = 0): Uint8Array { + return new Uint8Array(size); +} + +/** + * Where possible returns a Uint8Array of the requested size that references + * uninitialized memory. Only use if you are certain you will immediately + * overwrite every value in the returned `Uint8Array`. + */ +function _allocUnsafeNode(size = 0): Uint8Array { + const out = Buffer.allocUnsafe(size); + return new Uint8Array(out.buffer, out.byteOffset, out.byteLength); +} diff --git a/packages/as-sha256/src/index.ts b/packages/as-sha256/src/index.ts index 82c70073..23eb586e 100644 --- a/packages/as-sha256/src/index.ts +++ b/packages/as-sha256/src/index.ts @@ -1,4 +1,4 @@ -import {allocUnsafe} from "uint8arrays/alloc"; +import {allocUnsafe} from "./alloc"; import {newInstance} from "./wasm"; import {HashObject, byteArrayToHashObject, hashObjectToByteArray} from "./hashObject"; import SHA256 from "./sha256"; @@ -9,6 +9,8 @@ const wasmInputValue = ctx.input.value; const wasmOutputValue = ctx.output.value; const inputUint8Array = new Uint8Array(ctx.memory.buffer, wasmInputValue, ctx.INPUT_LENGTH); const outputUint8Array = new Uint8Array(ctx.memory.buffer, wasmOutputValue, ctx.PARALLEL_FACTOR * 32); +/** output uint8array, length 32, used to easily copy output data */ +const outputUint8Array32 = new Uint8Array(ctx.memory.buffer, wasmOutputValue, 32); const inputUint32Array = new Uint32Array(ctx.memory.buffer, wasmInputValue, ctx.INPUT_LENGTH); export function digest(data: Uint8Array): Uint8Array { @@ -258,13 +260,13 @@ function final(): Uint8Array { /** allocate memory and copy result */ function allocDigest(): Uint8Array { const out = allocUnsafe(32); - out.set(outputUint8Array); + out.set(outputUint8Array32); return out; } /** allocate memory and copy result at offset */ function allocDigestOffset(offset: number): Uint8Array { const out = allocUnsafe(32); - out.set(outputUint8Array, offset); + out.set(outputUint8Array.subarray(offset, offset + 32)); return out; } diff --git a/yarn.lock b/yarn.lock index 8719305b..bd8ec865 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2282,7 +2282,7 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^17", "@types/react@^17.0.35": +"@types/react@*", "@types/react@^17", "@types/react@^17.0", "@types/react@^17.0.35": version "17.0.80" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.80.tgz#a5dfc351d6a41257eb592d73d3a85d3b7dbcbb41" integrity sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA== From 11776d289a20a87dd5d2fcd6739fe04be6681ede Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 5 Aug 2024 18:41:22 -0400 Subject: [PATCH 3/5] chore: remove dependencies --- packages/as-sha256/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/as-sha256/package.json b/packages/as-sha256/package.json index 1f0cb8d8..fc628275 100644 --- a/packages/as-sha256/package.json +++ b/packages/as-sha256/package.json @@ -49,6 +49,5 @@ "@chainsafe/babel-plugin-inline-binary-import": "^1.0.3", "assemblyscript": "^0.27.24", "benchmark": "^2.1.4" - }, - "dependencies": {} + } } From 654a0fa8a351c7b145588eb1f9c40b30fc8079be Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 5 Aug 2024 18:41:54 -0400 Subject: [PATCH 4/5] chore: update lockfile --- yarn.lock | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index bd8ec865..c22a5dd5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8597,11 +8597,6 @@ multicast-dns@^6.0.1: dns-packet "^1.3.1" thunky "^1.0.2" -multiformats@^13.0.0: - version "13.2.2" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-13.2.2.tgz#16da153ee8b68d8c9da31b52176e90b3cd8b43ef" - integrity sha512-RWI+nyf0q64vyOxL8LbKtjJMki0sogRL/8axvklNtiTM0iFCVtHwME9w6+0P1/v4dQvsIg8A45oT3ka1t/M/+A== - multimatch@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" @@ -11973,13 +11968,6 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -uint8arrays@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-5.1.0.tgz#14047c9bdf825d025b7391299436e5e50e7270f1" - integrity sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww== - dependencies: - multiformats "^13.0.0" - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" From 33f03043242cab775a0dc691308f6e9ee4ac403e Mon Sep 17 00:00:00 2001 From: Cayman Date: Mon, 5 Aug 2024 18:42:38 -0400 Subject: [PATCH 5/5] chore: simplify comment --- packages/as-sha256/src/alloc.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/as-sha256/src/alloc.ts b/packages/as-sha256/src/alloc.ts index 87618932..3ee6c812 100644 --- a/packages/as-sha256/src/alloc.ts +++ b/packages/as-sha256/src/alloc.ts @@ -1,21 +1,16 @@ const isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null; -export const allocUnsafe = isNode ? _allocUnsafeNode : _allocUnsafe; - /** * Where possible returns a Uint8Array of the requested size that references * uninitialized memory. Only use if you are certain you will immediately * overwrite every value in the returned `Uint8Array`. */ +export const allocUnsafe = isNode ? _allocUnsafeNode : _allocUnsafe; + function _allocUnsafe(size = 0): Uint8Array { return new Uint8Array(size); } -/** - * Where possible returns a Uint8Array of the requested size that references - * uninitialized memory. Only use if you are certain you will immediately - * overwrite every value in the returned `Uint8Array`. - */ function _allocUnsafeNode(size = 0): Uint8Array { const out = Buffer.allocUnsafe(size); return new Uint8Array(out.buffer, out.byteOffset, out.byteLength);