UNPKG

@li0ard/kupyna

Version:

Kupyna (DSTU 7564:2014) hash function in pure TypeScript

50 lines (49 loc) 1.55 kB
import { dpad } from "../const.js"; import { uint64sToBytes } from "../utils.js"; /** Abstract class for Kupyna KMAC */ export class KupynaKMAC { key; outputLen; blockLen; threshold; h; ik; len; constructor(hash, kpad, key) { this.key = key; this.len = 0n; this.h = hash(); this.outputLen = this.h.outputLen; this.blockLen = this.h.blockLen; if (key.length != this.h.outputLen) throw new Error("Invalid key length"); this.h.update(key); this.h.update(kpad); this.ik = new Uint8Array(key.length); for (let i = 0; i < key.length; i++) this.ik[i] = ~key[i] & 0xFF; this.threshold = this.blockLen - 12; } /** Update hash buffer */ update(data) { this.len += BigInt(data.length); this.h.update(data); return this; } /** Finalize hash computation and return result as Uint8Array */ digest() { return this.clone().final(); } final() { let n = this.len; let pad_size; if (n < BigInt(this.threshold)) pad_size = (BigInt(this.threshold) - 1n) - n; else pad_size = (BigInt(this.blockLen) - 1n) - ((n - BigInt(this.threshold)) % BigInt(this.blockLen)); n *= 8n; this.h.update(dpad.slice(0, Number(pad_size + 1n))); this.h.update(uint64sToBytes(new BigUint64Array([n]))); this.h.update(dpad.slice(16, 20)); this.h.update(this.ik); return this.h.digest(); } }