diff options
author | Florian Dold <florian@dold.me> | 2022-12-23 12:58:26 +0100 |
---|---|---|
committer | Florian Dold <florian@dold.me> | 2022-12-23 13:19:41 +0100 |
commit | d98711cb51d13bb2da3682014c7c6e75d7fbb4f0 (patch) | |
tree | 827847cbb1c2d80c9f6b8241c46593a9a1da16f7 | |
parent | dc002f99a96752d3f0a10efe44a8a4d0503e8529 (diff) |
use native KDF / hash state if available
-rw-r--r-- | packages/taler-util/package.json | 2 | ||||
-rw-r--r-- | packages/taler-util/src/contract-terms.ts | 2 | ||||
-rw-r--r-- | packages/taler-util/src/kdf.ts | 40 | ||||
-rw-r--r-- | packages/taler-util/src/taler-crypto.test.ts | 3 | ||||
-rw-r--r-- | packages/taler-util/src/taler-crypto.ts | 63 | ||||
-rw-r--r-- | packages/taler-wallet-core/package.json | 2 | ||||
-rw-r--r-- | packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts | 2 |
7 files changed, 65 insertions, 49 deletions
diff --git a/packages/taler-util/package.json b/packages/taler-util/package.json index 6406f3f49..15197c086 100644 --- a/packages/taler-util/package.json +++ b/packages/taler-util/package.json @@ -22,7 +22,7 @@ "pretty": "prettier --write src" }, "devDependencies": { - "@types/node": "^18.8.5", + "@types/node": "^18.11.17", "ava": "^4.3.3", "esbuild": "^0.14.21", "prettier": "^2.5.1", diff --git a/packages/taler-util/src/contract-terms.ts b/packages/taler-util/src/contract-terms.ts index 3567b50d8..b906a1d7f 100644 --- a/packages/taler-util/src/contract-terms.ts +++ b/packages/taler-util/src/contract-terms.ts @@ -16,12 +16,12 @@ import { canonicalJson } from "./helpers.js"; import { Logger } from "./logging.js"; -import { kdf } from "./kdf.js"; import { decodeCrock, encodeCrock, getRandomBytes, hash, + kdf, stringToBytes, } from "./taler-crypto.js"; diff --git a/packages/taler-util/src/kdf.ts b/packages/taler-util/src/kdf.ts index dd8a2a459..8f4314340 100644 --- a/packages/taler-util/src/kdf.ts +++ b/packages/taler-util/src/kdf.ts @@ -16,7 +16,6 @@ import * as nacl from "./nacl-fast.js"; import { sha256 } from "./sha256.js"; -import { useNative } from "./taler-crypto.js"; export function sha512(data: Uint8Array): Uint8Array { return nacl.hash(data); @@ -59,42 +58,3 @@ export function hmacSha512(key: Uint8Array, message: Uint8Array): Uint8Array { export function hmacSha256(key: Uint8Array, message: Uint8Array): Uint8Array { return hmac(sha256, 64, key, message); } - -export function kdf( - outputLength: number, - ikm: Uint8Array, - salt?: Uint8Array, - info?: Uint8Array, -): Uint8Array { - if (useNative && "_kdf" in globalThis) { - // @ts-ignore - return globalThis._kdf(outputLength, ikm, salt, info); - } - salt = salt ?? new Uint8Array(64); - // extract - const prk = hmacSha512(salt, ikm); - - info = info ?? new Uint8Array(0); - - // expand - const N = Math.ceil(outputLength / 32); - const output = new Uint8Array(N * 32); - for (let i = 0; i < N; i++) { - let buf; - if (i == 0) { - buf = new Uint8Array(info.byteLength + 1); - buf.set(info, 0); - } else { - buf = new Uint8Array(info.byteLength + 1 + 32); - for (let j = 0; j < 32; j++) { - buf[j] = output[(i - 1) * 32 + j]; - } - buf.set(info, 32); - } - buf[buf.length - 1] = i + 1; - const chunk = hmacSha256(prk, buf); - output.set(chunk, i * 32); - } - - return output.slice(0, outputLength); -} diff --git a/packages/taler-util/src/taler-crypto.test.ts b/packages/taler-util/src/taler-crypto.test.ts index f154cb258..021730c7e 100644 --- a/packages/taler-util/src/taler-crypto.test.ts +++ b/packages/taler-util/src/taler-crypto.test.ts @@ -37,8 +37,9 @@ import { getRandomBytes, bigintToNaclArr, bigintFromNaclArr, + kdf, } from "./taler-crypto.js"; -import { sha512, kdf } from "./kdf.js"; +import { sha512 } from "./kdf.js"; import * as nacl from "./nacl-fast.js"; import { initNodePrng } from "./prng-node.js"; diff --git a/packages/taler-util/src/taler-crypto.ts b/packages/taler-util/src/taler-crypto.ts index 0f8d2d950..66ad478d3 100644 --- a/packages/taler-util/src/taler-crypto.ts +++ b/packages/taler-util/src/taler-crypto.ts @@ -22,7 +22,7 @@ * Imports. */ import * as nacl from "./nacl-fast.js"; -import { kdf } from "./kdf.js"; +import { hmacSha256, hmacSha512 } from "./kdf.js"; import bigint from "big-integer"; import { CoinEnvelope, @@ -76,7 +76,10 @@ interface NativeTartLib { keyExchangeEddsaEcdh(eddsaPriv: Uint8Array, ecdhPub: Uint8Array): Uint8Array; rsaBlind(hmsg: Uint8Array, bks: Uint8Array, rsaPub: Uint8Array): Uint8Array; rsaUnblind(blindSig: Uint8Array, rsaPub: Uint8Array, bks: Uint8Array): Uint8Array; - rsaVerify(hmsg: Uint8Array, rsaSig: Uint8Array, rsaPub: Uint8Array): boolean + rsaVerify(hmsg: Uint8Array, rsaSig: Uint8Array, rsaPub: Uint8Array): boolean; + hashStateInit(): any; + hashStateUpdate(st: any, data: Uint8Array): any; + hashStateFinish(st: any): Uint8Array; } // @ts-ignore @@ -158,6 +161,45 @@ export function encodeCrock(data: ArrayBuffer): string { return sb; } +export function kdf( + outputLength: number, + ikm: Uint8Array, + salt?: Uint8Array, + info?: Uint8Array, +): Uint8Array { + if (tart) { + return tart.kdf(outputLength, ikm, salt, info) + } + salt = salt ?? new Uint8Array(64); + // extract + const prk = hmacSha512(salt, ikm); + + info = info ?? new Uint8Array(0); + + // expand + const N = Math.ceil(outputLength / 32); + const output = new Uint8Array(N * 32); + for (let i = 0; i < N; i++) { + let buf; + if (i == 0) { + buf = new Uint8Array(info.byteLength + 1); + buf.set(info, 0); + } else { + buf = new Uint8Array(info.byteLength + 1 + 32); + for (let j = 0; j < 32; j++) { + buf[j] = output[(i - 1) * 32 + j]; + } + buf.set(info, 32); + } + buf[buf.length - 1] = i + 1; + const chunk = hmacSha256(prk, buf); + output.set(chunk, i * 32); + } + + return output.slice(0, outputLength); +} + + /** * HMAC-SHA512-SHA256 (see RFC 5869). */ @@ -708,7 +750,7 @@ const logger = new Logger("talerCrypto.ts"); export function hashCoinEvInner( coinEv: CoinEnvelope, - hashState: nacl.HashState, + hashState: TalerHashState, ): void { const hashInputBuf = new ArrayBuffer(4); const uint8ArrayBuf = new Uint8Array(hashInputBuf); @@ -785,7 +827,20 @@ export function eddsaVerify( return nacl.sign_detached_verify(msg, sig, eddsaPub); } -export function createHashContext(): nacl.HashState { +export interface TalerHashState { + update(data: Uint8Array): void; + finish(): Uint8Array; +} + +export function createHashContext(): TalerHashState { + if (tart) { + const t = tart; + const st = tart.hashStateInit(); + return { + finish: () => t.hashStateFinish(st), + update: (d) => t.hashStateUpdate(st, d), + } + } return new nacl.HashState(); } diff --git a/packages/taler-wallet-core/package.json b/packages/taler-wallet-core/package.json index 41448a01f..e5c19a39e 100644 --- a/packages/taler-wallet-core/package.json +++ b/packages/taler-wallet-core/package.json @@ -61,7 +61,7 @@ "dependencies": { "@gnu-taler/idb-bridge": "workspace:*", "@gnu-taler/taler-util": "workspace:*", - "@types/node": "^18.8.5", + "@types/node": "^18.11.17", "axios": "^0.27.2", "big-integer": "^1.6.51", "fflate": "^0.7.4", diff --git a/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts b/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts index f255e3cfd..634c891b6 100644 --- a/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts +++ b/packages/taler-wallet-core/src/crypto/workers/nodeThreadWorker.ts @@ -27,7 +27,7 @@ import { processRequestWithImpl } from "./worker-common.js"; const logger = new Logger("nodeThreadWorker.ts"); -const f = url.fileURLToPath(import.meta.url); +const f = import.meta.url ? url.fileURLToPath(import.meta.url) : '__not_available__'; const workerCode = ` // Try loading the glue library for embedded |