UNPKG

functionalscript

Version:

FunctionalScript is a purely functional subset of JavaScript

61 lines (60 loc) 1.96 kB
/** * Provides an implementation of HMAC (Hash-based Message Authentication Code). * * https://en.wikipedia.org/wiki/HMAC * * @module * * @example * * ```ts * import { vec } from '../../types/bit_vec/module.f.ts' * import { msbUtf8 } from '../../text/module.f.ts' * import { sha256 } from '../sha2/module.f.ts' * * const r = hmac(sha256)(msbUtf8('key'))(msbUtf8('The quick brown fox jumps over the lazy dog')) * if (r !== vec(256n)(0xf7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8n)) { throw r } * ``` */ import { length } from "../../types/bit_vec/module.f.js"; import { empty, msb, vec, vec8 } from "../../types/bit_vec/module.f.js"; import { flip } from "../../types/function/module.f.js"; import { repeat } from "../../types/monoid/module.f.js"; import { computeSync } from "../sha2/module.f.js"; const { concat } = msb; /** * Outer padding. */ const oPad = vec8(0x5cn); /** * Inner padding. */ const iPad = vec8(0x36n); /** * Repeats a vector to create a padded block of the desired length. */ const padRepeat = repeat({ identity: empty, operation: concat }); /** * Generates an HMAC (Hash-based Message Authentication Code) using the specified SHA-2 hash function. * * @param sha2 - The SHA-2 hash function implementation to use. * @returns - A function that takes a key and returns another function * that takes a message and computes the HMAC. */ export const hmac = (sha2) => { const { blockLength } = sha2; const p = flip(padRepeat)(blockLength >> 3n); const ip = p(iPad); const op = p(oPad); const c = computeSync(sha2); const vbl = vec(blockLength); const xor = (a) => (b) => vbl(a ^ b); return k => m => { const k1 = length(k) > blockLength ? c([k]) : k; const k2 = concat(k1)(vec(blockLength - length(k1))(0n)); const xk2 = xor(k2); const f = (p, msg) => c([xk2(p), msg]); const m1 = f(ip, m); return f(op, m1); }; };