UNPKG

@li0ard/crapto1_ts

Version:
212 lines (211 loc) 6.1 kB
/** * Get bit of `num` at position `index` * @param num Number * @param index Index * @returns {number} */ export const bit = (num, index) => { return ((num >>> index) & 1); }; /** * Get bit of reversed endian 32-bit `num` at position `index` * @param num Word * @param index Index * @returns {number} */ export const bebit = (num, index) => { return bit(num, index ^ 24); }; /** * Filter function of Crypto1. Compute one bit of keystream from LFSR bits * @param x LFSR bits * @returns {number} */ export const filter = (x) => { let f = 0; f |= (0xf22c0 >>> (x & 0xf) & 16) !== 0 ? 16 : 0; f |= (0x6c9c0 >>> (x >>> 4 & 0xf) & 8) !== 0 ? 8 : 0; f |= (0x3c8b0 >>> (x >>> 8 & 0xf) & 4) !== 0 ? 4 : 0; f |= (0x1e458 >>> (x >>> 12 & 0xf) & 2) !== 0 ? 2 : 0; f |= (0x0d938 >>> (x >>> 16 & 0xf) & 1) !== 0 ? 1 : 0; return bit(0xEC57E80A, f); }; /** * Get parity from number * @param x Number * @returns {number} */ export const parity = (x) => { x ^= x >>> 16; x ^= x >>> 8; x ^= x >>> 4; return bit(0x6996, x & 0xf); }; /** * Binary search for the first occurence of stop's MSB in sorted */ export const binsearch = (data, start, stop) => { let mid, val = data[stop] & 0xff000000; while (start !== stop) { mid = (stop - start) >> 1; if ((data[start + mid] ^ 0x80000000) > (val ^ 0x80000000)) { stop = start + mid; } else { start += mid + 1; } } return start; }; export const quicksort = (data, start, stop) => { let it = start + 1, rit = stop, t; if (it > rit) return; while (it < rit) { if ((data[it] ^ 0x80000000) <= (data[start] ^ 0x80000000)) { ++it; } else if ((data[rit] ^ 0x80000000) > (data[start] ^ 0x80000000)) { --rit; } else { t = data[it]; data[it] = data[rit]; data[rit] = t; } } if ((data[rit] ^ 0x80000000) >= (data[start] ^ 0x80000000)) { --rit; } if (rit !== start) { t = data[rit]; data[rit] = data[start]; data[start] = t; } quicksort(data, start, rit - 1); quicksort(data, rit + 1, stop); }; /** * Helper, calculates the partial linear feedback contributions and puts in MSB * @param data Input number * @param item Input index * @param mask1 * @param mask2 * @returns {void} */ export const update_contribution = (data, item, mask1, mask2) => { let p = data[item] >>> 25; p = p << 1 | parity(data[item] & mask1); p = p << 1 | parity(data[item] & mask2); data[item] = p << 24 | (data[item] & 0xffffff); }; /** * Using a bit of the keystream extend the table of possible lfsr states (complex version) * @param data Result table * @param tbl Array of even/odd bits of lfsr * @param size Size of array * @param bit Bit of keystream * @param m1 mask1 * @param m2 mask2 * @param input Value that was fed into lfsr at time keystream was generated * @returns {number} */ export const extend_table = (data, tbl, size, bit, m1, m2, input) => { input <<= 24; for (data[tbl] <<= 1; tbl <= size; data[++tbl] <<= 1) { if ((filter(data[tbl]) ^ filter(data[tbl] | 1)) !== 0) { data[tbl] |= filter(data[tbl]) ^ bit; update_contribution(data, tbl, m1, m2); data[tbl] ^= input; } else if (filter(data[tbl]) === bit) { data[++size] = data[tbl + 1]; data[tbl + 1] = data[tbl] | 1; update_contribution(data, tbl, m1, m2); data[tbl++] ^= input; update_contribution(data, tbl, m1, m2); data[tbl] ^= input; } else { data[tbl--] = data[size--]; } } return size; }; /** * Using a bit of the keystream extend the table of possible lfsr states (simple version) * @param tbl Array of even/odd bits of lfsr * @param size Size of array * @param bit Bit of keystream * @returns {number} */ export const extend_table_simple = (tbl, size, bit) => { let i = 0; for (tbl[i] <<= 1; i <= size; tbl[++i] <<= 1) { if ((filter(tbl[i]) ^ filter(tbl[i] | 1)) !== 0) { tbl[i] |= filter(tbl[i]) ^ bit; } else if (filter(tbl[i]) === bit) { tbl[++size] = tbl[++i]; tbl[i] = tbl[i - 1] | 1; } else { tbl[i--] = tbl[size--]; } } return size; }; export const oddByteParity = [ 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 ]; /** * Return odd parity of unsigned 8-bit `x` * @param x Number * @returns {number} */ export const oddParity8 = (x) => { return oddByteParity[x]; }; /** * Return even parity of unsigned 8-bit `x` * @param x Number * @returns {number} */ export const evenParity8 = (x) => { return oddParity8(x) ^ 1; }; /** * Return even parity of unsigned 32-bit `x` * @param x Number * @returns {number} */ export const evenParity32 = (x) => { x ^= x >> 16; x ^= x >> 8; return evenParity8(x & 0xFF); }; /** * Swaps endianness of given number * @param x Number to swap * @returns {number} */ export const swapendian = (x) => { x = (x >>> 8 & 0xff00ff) | (x & 0xff00ff) << 8; x = x >>> 16 | x << 16; return x; };