/** F6 — Crypto monomers: MC_48–MC_55 (Web Crypto API) */ export const hashSha256 = async (data: string | Uint8Array): Promise => { const buf = typeof data === 'string' ? new TextEncoder().encode(data) : data; const ab = new ArrayBuffer(buf.byteLength); new Uint8Array(ab).set(buf); return new Uint8Array(await crypto.subtle.digest('SHA-256', ab)); }; export const hashHex = async (data: string | Uint8Array): Promise => Array.from(await hashSha256(data)).map(b => b.toString(16).padStart(2, '0')).join(''); export const xorBytes = (a: Uint8Array, b: Uint8Array): Uint8Array => { const out = new Uint8Array(Math.min(a.length, b.length)); for (let i = 0; i < out.length; i++) out[i] = (a[i] ?? 0) ^ (b[i] ?? 0); return out; }; export const rotateLeft = (v: number, n: number): number => { const s = ((n % 32) + 32) % 32; return ((v << s) | (v >>> (32 - s))) >>> 0; }; export const rotateRight = (v: number, n: number): number => { const s = ((n % 32) + 32) % 32; return ((v >>> s) | (v << (32 - s))) >>> 0; }; export const constantEq = (a: Uint8Array, b: Uint8Array): boolean => { if (a.length !== b.length) return false; let d = 0; for (let i = 0; i < a.length; i++) d |= (a[i] ?? 0) ^ (b[i] ?? 0); return d === 0; }; export const zeroBytes = (n: number): Uint8Array => new Uint8Array(Math.min(n, 4096)); export const bytesToHex = (data: Uint8Array): string => Array.from(data).map(b => b.toString(16).padStart(2, '0')).join('');