use native KDF / hash state if available
This commit is contained in:
parent
dc002f99a9
commit
d98711cb51
@ -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",
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user