From e98c5ba843310c3f6ad14ba4f10d0480fb6c10e2 Mon Sep 17 00:00:00 2001 From: microshine Date: Thu, 24 Feb 2022 23:37:40 +0300 Subject: [PATCH] fetch: Support shake128 and shake256 mechanisms --- README.md | 2 ++ src/mechs/index.ts | 1 + src/mechs/shake/crypto.ts | 11 +++++++++++ src/mechs/shake/index.ts | 3 +++ src/mechs/shake/shake128.ts | 12 ++++++++++++ src/mechs/shake/shake256.ts | 12 ++++++++++++ src/subtle.ts | 8 ++++++++ test/crypto.ts | 18 ++++++++++++++++++ 8 files changed, 67 insertions(+) create mode 100644 src/mechs/shake/crypto.ts create mode 100644 src/mechs/shake/index.ts create mode 100644 src/mechs/shake/shake128.ts create mode 100644 src/mechs/shake/shake256.ts diff --git a/README.md b/README.md index cc5349f..4102468 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,8 @@ npm install @peculiar/webcrypto | PBKDF2 | | | X | | | | X | | DES-CBC2| X | | X | | X | X | | | DES-EDE3-CBC2| X | | X | | X | X | | +| shake1282| | X | | | | | | +| shake2562| | X | | | | | | 1 Mechanism supports extended list of named curves `P-256`, `P-384`, `P-521`, `K-256`, `brainpoolP160r1`, `brainpoolP160t1`, `brainpoolP192r1`, `brainpoolP192t1`, `brainpoolP224r1`, `brainpoolP224t1`, `brainpoolP256r1`, `brainpoolP256t1`, `brainpoolP320r1`, `brainpoolP320t1`, `brainpoolP384r1`, `brainpoolP384t1`, `brainpoolP512r1`, and `brainpoolP512t1` diff --git a/src/mechs/index.ts b/src/mechs/index.ts index dfbd8bf..238ad11 100644 --- a/src/mechs/index.ts +++ b/src/mechs/index.ts @@ -7,3 +7,4 @@ export * from "./sha"; export * from "./pbkdf"; export * from "./hmac"; export * from "./hkdf"; +export * from "./shake"; diff --git a/src/mechs/shake/crypto.ts b/src/mechs/shake/crypto.ts new file mode 100644 index 0000000..35a6ce9 --- /dev/null +++ b/src/mechs/shake/crypto.ts @@ -0,0 +1,11 @@ +import crypto from "crypto"; + +export class ShakeCrypto { + + public static digest(algorithm: Algorithm, data: ArrayBuffer) { + const hash = crypto.createHash(algorithm.name.toLowerCase()) + .update(Buffer.from(data)).digest(); + return new Uint8Array(hash).buffer; + } + +} diff --git a/src/mechs/shake/index.ts b/src/mechs/shake/index.ts new file mode 100644 index 0000000..897ba0f --- /dev/null +++ b/src/mechs/shake/index.ts @@ -0,0 +1,3 @@ +export * from "./crypto"; +export * from "./shake128"; +export * from "./shake256"; diff --git a/src/mechs/shake/shake128.ts b/src/mechs/shake/shake128.ts new file mode 100644 index 0000000..f45fffd --- /dev/null +++ b/src/mechs/shake/shake128.ts @@ -0,0 +1,12 @@ +import * as core from "webcrypto-core"; +import { ShakeCrypto } from "./crypto"; + +export class Shake128Provider extends core.ProviderCrypto { + public name = "shake128"; + public usages = []; + + public async onDigest(algorithm: Algorithm, data: ArrayBuffer): Promise { + return ShakeCrypto.digest(algorithm, data); + } + +} diff --git a/src/mechs/shake/shake256.ts b/src/mechs/shake/shake256.ts new file mode 100644 index 0000000..e323256 --- /dev/null +++ b/src/mechs/shake/shake256.ts @@ -0,0 +1,12 @@ +import * as core from "webcrypto-core"; +import { ShakeCrypto } from "./crypto"; + +export class Shake256Provider extends core.ProviderCrypto { + public name = "shake256"; + public usages = []; + + public async onDigest(algorithm: Algorithm, data: ArrayBuffer): Promise { + return ShakeCrypto.digest(algorithm, data); + } + +} diff --git a/src/subtle.ts b/src/subtle.ts index f9f32b3..a4a91f3 100644 --- a/src/subtle.ts +++ b/src/subtle.ts @@ -11,6 +11,7 @@ import { Pbkdf2Provider, RsaEsProvider, RsaOaepProvider, RsaPssProvider, RsaSsaProvider, Sha1Provider, Sha256Provider, Sha384Provider, Sha512Provider, + Shake128Provider, Shake256Provider, } from "./mechs"; export class SubtleCrypto extends core.SubtleCrypto { @@ -63,6 +64,13 @@ export class SubtleCrypto extends core.SubtleCrypto { //#endregion const nodeMajorVersion = /^v(\d+)/.exec(process.version)?.[1]; + if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 12) { + //#region SHAKE + this.providers.set(new Shake128Provider()); + this.providers.set(new Shake256Provider()); + //#endregion + } + if (nodeMajorVersion && parseInt(nodeMajorVersion, 10) >= 14) { //#region EdDSA this.providers.set(new EdDsaProvider()); diff --git a/test/crypto.ts b/test/crypto.ts index 69cde13..14ea050 100644 --- a/test/crypto.ts +++ b/test/crypto.ts @@ -226,4 +226,22 @@ context("Crypto", () => { assert.strictEqual(hmacKey.algorithm.name, "HMAC"); }); + context("shake digest", () => { + + const data = Buffer.from("test data"); + + it("shake128", async () => { + const hash = await crypto.subtle.digest("shake128", data); + + assert.strictEqual(Buffer.from(hash).toString("hex"), "ae3bdcf04986a8e7ddd99ac948254693"); + }); + + it("shake256", async () => { + const hash = await crypto.subtle.digest("shake256", data); + + assert.strictEqual(Buffer.from(hash).toString("hex"), "be15253026b9a85e01ae54b1939284e8e514fbdad2a3bd5c1c0f437e60548e26"); + }); + + }); + });