📄 lili-ii-ref.c
字号:
/** * @file lili-ii-ref.c * * Definitions for the LILI-II keystream generator. * * The LILI-II Keystream generator is defined in * [CDF02] Clark, A., Dawson, E., Fuller, J., Golic, J., Lee, H-J, * Millan, W., Moon, S-J., and Simpson, L. The LILI-II Keystream * Generator, Proceedings of ACISP 2002, Lecture Notes in * Computer Science 2384, Springer-Verlag, 2002, pp. 25 - 39. * * @author Information Security Institute * Queensland University of Technology * Brisbane, Australia * @version 1.1 * @date 2006 */#include "lili-ii.h"/**--------------------------------------------------------------------------- * LFSR Macros * * These macros provide an easy way to retrieve a bit from an LFSR that * spans multiple words. The macros are provided with two assumptions * a) the most significant bit of the LFSR is stored in the most * significant bit of the first word. * b) that post-fix padding is used when the size of the LFSR is not * divisible by the size of the machine word *--------------------------------------------------------------------------*/#define BITS_IN_WORD 8#define ADDRESS_MASK (BITS_IN_WORD - 1)#define LOG_BITS_IN_WORD 3/* Select the machine word containing stage <i> from the <s>-bit register. */#define REG_WORD(lfsr, s, i) \ lfsr[(s-1-i) >> LOG_BITS_IN_WORD]/* Calculate the location of the bit <i> within the selected 8-bit word of * the <s>-bit register. */#define REG_OFFSET(s, i) \ ((BITS_IN_WORD + i - s) & ADDRESS_MASK)/* Extract the <i>th bit from an <lfsr> with a state of <s> bits. */#define GET_BIT(lfsr, s, i) \ ((REG_WORD(lfsr, s, i) >> REG_OFFSET(s, i)) & 0x1)/** * Specialized macros to extract from the LILI-II C and D registers. */#define LFSR_C_BIT(c, index) GET_BIT(c, 128, index)#define LFSR_D_BIT(d, index) GET_BIT(d, 127, index)/**--------------------------------------------------------------------------- * Forward declaration of auxiliary functions *--------------------------------------------------------------------------*/void lili2_get_eiv(const u8* iv, const u8 iv_length, u8* eiv);u8 lili2_clock_c(u8 *c);u8 lili2_clock_d(u8 *d, const u16 clocks);u8 TT(const u16 index);/**--------------------------------------------------------------------------- * LILI-II Keystream Generator API *--------------------------------------------------------------------------*//** * Carry out the LILI-II resynchronization algorithm, given an 128-bit key * and variable-length initialization vector. * * @param ctx [In/Out] LILI-II context (pre-allocated) * @param key [In] 128-bit key * @param iv [In] IV * @param iv_length [In] IV length in bits (usually 128) * @returns LILI_INITIALIZATION_OK if successful. * LILI_INVALID_STATE if the all-zero state occurs. * */int lili2_key_init(LILI2Ctx *ctx, const u8 *key, const u8 *iv, const u8 iv_length){ u8 *c = ctx->c; /* shorthand */ u8 *d = ctx->d; /* shorthand */ u8 buffer[LILI2_INTERNAL_STATE_SIZE]; u8 eiv[LILI2_IV_SIZE]; u16 i = 0; int status = LILI2_INITIALIZATION_OK; u8 c_zeroes = 0; u8 d_zeroes = 0; /** * Preliminary phase: form a 128-bit extended IV from the IV */ lili2_get_eiv(iv, iv_length, eiv); /** * Resynchronization phase 1: * * - Populate initial state of C using key xor iv. * - Populate initial state of D using k' xor iv' where k' is the key * with the first bit deleted, and iv' the iv with the last bit deleted */ for (i = 0; i < LILI2_KEY_SIZE - 1; i++) { c[i] = key[i]; d[i] = (key[i] << 1) ^ (key[i+1] >> (BITS_IN_WORD - 1)); } c[LILI2_KEY_SIZE - 1] = key[LILI2_KEY_SIZE - 1]; d[LILI2_KEY_SIZE - 1] = key[LILI2_KEY_SIZE - 1] << 1; for (i = 0; i < LILI2_IV_SIZE; i++) { c[i] ^= eiv[i]; d[i] ^= eiv[i]; /* the last bit of iv is implicitly ignored */ } /** * Resynchronization phase 2: * * Given the initial state of phase 1, generate 255 bits of keystream, * which replaces the contents of registers C and D. * * Note that lili2_keystream post-fix pads the keystream buffer, as does * the D register, so the 256th 'null' keystream bit is effectively * ignored. */ lili2_keystream(ctx, buffer, 255); for (i = 0; i < LILI2_REG_C_LEN; i++) { c[i] = buffer[i]; } for (i = 0; i < LILI2_REG_D_LEN; i++) { d[i] = buffer[i + LILI2_REG_C_LEN]; } /** * Resynchronization phase 3: * * Given the initial state of phase 2, generate 255 bits of keystream, * which replaces the contents of registers C and D. */ lili2_keystream(ctx, buffer, 255); for (i = 0; i < LILI2_REG_C_LEN; i++) { c[i] = buffer[i]; } for (i = 0; i < LILI2_REG_D_LEN; i++) { d[i] = buffer[i + LILI2_REG_C_LEN]; } d[LILI2_REG_D_LEN - 1] &= 0xFE; /** * Resynchronization phase 4: * * Generate an error on the all-zero state for either register. */ for (i = 0; i < LILI2_REG_C_LEN; i++) { c_zeroes += (ctx->c[i] ? 0 : 1); } for (i = 0; i < LILI2_REG_D_LEN; i++) { d_zeroes += (ctx->d[i] ? 0 : 1); } if ((c_zeroes == LILI2_REG_C_LEN) || (d_zeroes == LILI2_REG_D_LEN)) { status = LILI2_INVALID_STATE; } return status;}/** * Generate keystream using the LILI-II keystream generator * * @param ctx [In] initialized LILI-II context * @param keystream [Out] repository for LILI-II keystream * @param keystream_len [In] number of bits of keystream requested * @returns number of bits of keystream actually generated * @note <keystream> must be preallocated with ceil(<keystream_len>/32) * words of memory. This procedure overwrites the contents of * <keystream>. */u32 lili2_keystream(LILI2Ctx *ctx, u8 *keystream, const u32 keystream_len){ u32 bits_generated = 0; u32 ks_index = 0; u32 keystream_required = keystream_len; keystream[0] = 0; while ((keystream_required--) > 0) { /** * Clock the clock control register */ u8 clocking_bits = lili2_clock_c(ctx->c); /** * Clock the data generation register */ u8 output = lili2_clock_d(ctx->d, clocking_bits); /** * Assemble the keystream by adding the most recent output bit */ keystream[ks_index] = (keystream[ks_index] << 1) | output; ++bits_generated; if ((bits_generated % 8) == 0) { ++ks_index; keystream[ks_index] = 0; } } /** * postfix pad the last byte of keystream */ keystream[ks_index] <<= (7 - ((bits_generated-1) % 8)); return bits_generated;}/**--------------------------------------------------------------------------- * LILI-II Auxiliary Functions *--------------------------------------------------------------------------*//** * Clock the LILI-II C register, and return the output of the register, * formed by combining bits 00 and 126 * * @param c [In] The 128-bit LILI-II C register * @returns a two bit value. * * @note The indices of the terms in the primitive polynomial for * register C are * {128, 126, 125, 124, 123, 122, 119, 117, 115, 111, 108, * 106, 105, 104, 103, 102, 96, 94, 90, 87, 82, 81, * 80, 79, 77, 74, 73, 72, 71, 70, 67, 66, 65, * 61, 60, 58, 57, 56, 55, 53, 52, 51, 50, 49, * 47, 44, 43, 40, 39, 36, 35, 30, 29, 25, 23, * 18, 17, 16, 15, 14, 11, 9, 8, 7, 6, 1, 0 }; * * With this many taps, a Galois configuration is assumed, as the * clocking is linear in the degree of the polynomial, rather than * the number of terms (which occurs for a Fibonacci configuration) * * Bit numbering within the polynomial is somewhat contentious. A * standardized approach seems to be to number from 0 to 128 in the * direction of the shifting for Galois configurations, and in the * reverse for Fibonacci configurations. See the excellent article at * http://www.newwaveinstruments.com/resources/articles/ * m_sequence_linear_feedback_shift_register_lfsr.htm * * So we adopt the following notation * +----------|----------|----------|----------+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -