UNPKG

@li0ard/crapto1_ts

Version:
80 lines (79 loc) 2.2 kB
import { Crypto1State } from "./state"; import { bebit, bit, filter, oddParity8, parity, swapendian } from "./utils"; export const LF_POLY_ODD = 0x29CE5C; export const LF_POLY_EVEN = 0x870804; /** * Helper used to obscure the keystream during authentication * @param x Input data * @param n Keystream number * @returns {number} */ export const prng_successor = (x, n) => { x = swapendian(x); while ((n--) > 0) { x = x >>> 1 | (x >>> 16 ^ x >>> 18 ^ x >>> 19 ^ x >>> 21) << 31; } return swapendian(x); }; /** * Generate keystream for words (uint32) * @param s State * @param input Input word * @param isEncrypted Is input word encrypted? * @returns {number} */ export const crypto1_word = (s, input, isEncrypted = false) => { let i, ret = 0; for (i = 0; i < 32; ++i) { ret |= crypto1_bit(s, bebit(input, i), isEncrypted) << (i ^ 24); } return ret; }; /** * Generate keystream for bytes * @param s State * @param input Input byte * @param isEncrypted Is input byte encrypted? * @returns {number} */ export const crypto1_byte = (s, input, isEncrypted = false) => { let i, ret = 0; for (i = 0; i < 8; ++i) { ret |= crypto1_bit(s, bit(input, i), isEncrypted) << i; } return ret; }; /** * Generate keystream for bits * @param s State * @param input Input bit * @param isEncrypted Is input bit encrypted? * @returns {number} */ export const crypto1_bit = (s, input, isEncrypted = false) => { let feedin; let ret = filter(s.odd); feedin = ret & ((isEncrypted) ? 1 : 0); feedin ^= ((input !== 0) ? 1 : 0); feedin ^= LF_POLY_ODD & s.odd; feedin ^= LF_POLY_EVEN & s.even; s.even = s.even << 1 | parity(feedin); s.odd ^= s.even; s.even ^= s.odd; s.odd ^= s.even; return ret; }; /** * Proceed encryption/decryption process * @param s State * @param data Input data * @param isIn Use input data as input word for keystream generation? * @returns {number[]} */ export const encrypt = (s, data, isIn = false) => { let result = []; for (let i = 0; i < data.length; i++) { result[i] = data[i] ^ crypto1_byte(s, isIn ? data[i] : 0); } return result; };