Pull out pbkdf2Sha512Subtle

This commit is contained in:
Simon Warta 2022-02-27 19:41:40 +01:00
parent c2a0622475
commit 1b49d85dd7
2 changed files with 55 additions and 19 deletions

View File

@ -1,6 +1,7 @@
import { fromHex, toAscii, toUtf8 } from "@cosmjs/encoding";
import { assert } from "@cosmjs/utils";
import { pbkdf2Sha512 } from "./pbkdf2";
import { getSubtle, pbkdf2Sha512, pbkdf2Sha512Subtle } from "./pbkdf2";
interface TestVector {
secret: Uint8Array;
@ -115,7 +116,26 @@ describe("pbkdf2", () => {
for (const [index, test] of brycxTests.entries()) {
const { secret, salt, iterations, keylen, expected } = test;
const hash = await pbkdf2Sha512(secret, salt, iterations, keylen);
expect(hash).withContext(`Index ${index}`).toEqual(expected);
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
}
});
});
describe("pbkdf2Sha512Subtle", () => {
it("works", async () => {
const subtle = await getSubtle();
assert(subtle);
{
const { secret, salt, iterations, keylen, expected } = botanTest;
const hash = await pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
expect(hash).toEqual(expected);
}
for (const [index, test] of brycxTests.entries()) {
const { secret, salt, iterations, keylen, expected } = test;
const hash = await pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
}
});
});

View File

@ -1,4 +1,6 @@
async function getSubtle(): Promise<any | undefined> {
import { assert } from "@cosmjs/utils";
export async function getSubtle(): Promise<any | undefined> {
const g: any = globalThis;
let subtle = g.crypto && g.crypto.subtle;
if (!subtle) {
@ -10,6 +12,35 @@ async function getSubtle(): Promise<any | undefined> {
return subtle;
}
export async function pbkdf2Sha512Subtle(
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
subtle: any,
secret: Uint8Array,
salt: Uint8Array,
iterations: number,
keylen: number,
): Promise<Uint8Array> {
assert(subtle, "Argument subtle is falsy");
assert(typeof subtle === "object", "Argument subtle is not of type object");
assert(typeof subtle.importKey === "function", "subtle.importKey is not a function");
assert(typeof subtle.deriveBits === "function", "subtle.deriveBits is not a function");
return subtle.importKey("raw", secret, { name: "PBKDF2" }, false, ["deriveBits"]).then((key: Uint8Array) =>
subtle
.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: iterations,
hash: { name: "SHA-512" },
},
key,
keylen * 8,
)
.then((buffer: ArrayBuffer) => new Uint8Array(buffer)),
);
}
/**
* A pbkdf2 implementation for BIP39. This is not exported at package level and thus a private API.
*/
@ -21,22 +52,7 @@ export async function pbkdf2Sha512(
): Promise<Uint8Array> {
const subtle = await getSubtle();
if (subtle) {
return subtle
.importKey("raw", secret, { name: "PBKDF2" }, false, ["deriveBits"])
.then((key: Uint8Array) =>
subtle
.deriveBits(
{
name: "PBKDF2",
salt: salt,
iterations: iterations,
hash: { name: "SHA-512" },
},
key,
keylen * 8,
)
.then((buffer: ArrayBuffer) => new Uint8Array(buffer)),
);
return pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
} else {
const module = await import("crypto");
return new Promise((resolve, reject) => {