📄 lili-ii-ref.c
字号:
* shift <- | c[0] | c[1] | c[2] | c[3] |<- feedback * +----------|----------|----------|----------+ * 127 96 64 32 0 */u8 lili2_clock_c(u8 *c){ static u8 galois_constants[2][16] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x7C, 0xA8, 0x97, 0xC1, 0x44, 0x87, 0xA7, 0xCE, 0x37, 0xBE, 0x99, 0x98, 0x62, 0x87, 0xCB, 0xC3 } }; /** * Extract the clocking bits according to the function * fc(x0, x126) = 2(x0) + x126 + 1 */ u8 output = 1 + 2 * LFSR_C_BIT(c, 0) + LFSR_C_BIT(c, 126); /** * Clock the LFSR by shifting to the left, then xoring in the * constants (if and only if the shifted-out bit is 1). */ u8 clocked_bit = LFSR_C_BIT(c, 127); u8 i; for (i = 0; i < 15; i++) { c[i] = ((c[i] << 1) | (c[i+1] >> (BITS_IN_WORD - 1))); c[i] ^= galois_constants[clocked_bit][i]; } c[15] = (c[15] << 1) ^ galois_constants[clocked_bit][15]; return output;}/** * Clock the LILI-II D register, and return the output of the register * filtered through a boolean function * * @param d [In] the 127-bit LILI-II D register * @param clocks [In] number of times to clock the register * @returns a one-bit value * */u8 lili2_clock_d(u8 *d, const u16 clocks){ static u8 galois_constants[2][16] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x06, 0x08, 0x19, 0x46, 0xA5, 0x34, 0x3A, 0x66, 0x96, 0xAA, 0xD3, 0x70, 0xF5, 0xF8, 0x8B, 0xBE } }; u16 i, j; u8 clocked_bit; /** * The specification is clear that the output bit is formed before * LFSR_D is clocked. */ /** * Extract the twelve bits used to get the D register output */ u16 z_in = (LFSR_D_BIT(d, 0) << 11) | (LFSR_D_BIT(d, 1) << 10) | (LFSR_D_BIT(d, 3) << 9) | (LFSR_D_BIT(d, 7) << 8) | (LFSR_D_BIT(d, 12) << 7) | (LFSR_D_BIT(d, 20) << 6) | (LFSR_D_BIT(d, 30) << 5) | (LFSR_D_BIT(d, 44) << 4) | (LFSR_D_BIT(d, 65) << 3) | (LFSR_D_BIT(d, 80) << 2) | (LFSR_D_BIT(d, 96) << 1) | LFSR_D_BIT(d, 122); u8 z = TT(z_in); /** * Clock the LFSR by shifting to the left, then xoring in the * constants (if and only if the shifted-out bit is 1). */ for (i = 0; i < clocks; i++) { clocked_bit = LFSR_D_BIT(d, 126); for (j = 0; j < 15; j++) { d[j] = ((d[j] << 1) | (d[j+1] >> (BITS_IN_WORD - 1))); d[j] ^= galois_constants[clocked_bit][j]; } d[15] = (d[15] << 1) ^ galois_constants[clocked_bit][15]; } return z; }/** * Simple lookup table that returns a single bit, the location of which is * determined by a 12-bit index. */u8 TT(const u16 index){ static u32 f[] = { 0x965A69A5, 0x69A5965A, 0x69A5965A, 0x69A5965A, 0x66AA9955, 0x995566AA, 0x995566AA, 0x995566AA, 0x3CF0C30F, 0xC30F3CF0, 0xC20D3EF1, 0xC20D3EF1, 0xCC0033FF, 0x33FFCC00, 0x31FECD02, 0x31FECD02, 0x69A5965A, 0x965A69A5, 0x69A5965A, 0x69A5965A, 0x995566AA, 0x66AA9955, 0x995566AA, 0x995566AA, 0xC30F3CF0, 0x3CF0C30F, 0xC10E3DF2, 0xC10E3DF2, 0x33FFCC00, 0xCC0033FF, 0x32FDCE01, 0x32FDCE01, 0x69A569A5, 0x965A965A, 0x4E724F71, 0x4C714F73, 0x99559955, 0x66AA66AA, 0xBE83BC81, 0xBC80BD42, 0xC30FC30F, 0x3CF03CF0, 0xDAE1DDEE, 0xDAE7D7E2, 0x33FF33FF, 0xCC00CC00, 0x16221B27, 0x1E2C1A20, 0x965A965A, 0x69A569A5, 0xB08FB28C, 0xB38CB38D, 0x66AA66AA, 0x99559955, 0x407F427D, 0x437C427D, 0x3CF03CF0, 0xC30FC30F, 0x1A201328, 0x1F2F102E, 0xCC00CC00, 0x33FF33FF, 0xD9EDD0E5, 0xD8E5DBE8, 0x965A69A5, 0x69A5965A, 0xB4874B78, 0xB4874B78, 0x66AA9955, 0x995566AA, 0x4477BB88, 0x4477BB88, 0x3CF0C30F, 0xC30F3CF0, 0x2E1DD2E1, 0x2E1DD2E1, 0xCC0033FF, 0x33FFCC00, 0xEDDE1122, 0xEDDE1122, 0x965A69A5, 0x69A5965A, 0x4B78B487, 0x4B78B487, 0x66AA9955, 0x995566AA, 0xBB884477, 0xBB884477, 0x3CF0C30F, 0xC30F3CF0, 0xD2E12E1D, 0xD2E12E1D, 0xCC0033FF, 0x33FFCC00, 0x1122EDDE, 0x1122EDDE, 0x69A569A5, 0x965A965A, 0x49714478, 0x497D4F7B, 0x99559955, 0x66AA66AA, 0xB28EB782, 0xBA86B984, 0xC10EC20D, 0x3DF23EF1, 0x66AD68AC, 0x68A76CA3, 0x32FD31FE, 0xCE01CD02, 0x67A065AD, 0x60A067A7, 0x69A569A5, 0x965A965A, 0x4F794674, 0x4A794070, 0x99559955, 0x66AA66AA, 0xB48BBA8F, 0xB583B58E, 0xC20DC10E, 0x3EF13DF2, 0x9E529553, 0x99529859, 0x31FE32FD, 0xCD02CE01, 0x9756955E, 0x995F915D }; /** * Break the twelve-bit index into a seven-bit word * selector, and a five bit bit selector */ u32 word_index = index >> 5; u32 bit_mask = 31-(index & 0x1F); return (u8)(f[word_index] >> bit_mask) & 0x1;}/** * Turn an IV into an extended 128-bit IV (EIV). There are four cases: * a) IV is 128 bits, so copy directly into EIV. * b) IV is less than 128 bits, but a multiple of 8 bits, so copy bytewise * into IV, and repeat for as many bytes as necessary. * c) IV is less than 128 bits, but not a multiple of 8 bits, so copy bitwise * into IV, and repeat for as many bits as necessary * d) IV is more than 128, so truncate to 128 bits and treat as for case a). */void lili2_get_eiv(const u8* iv, const u8 iv_length, u8* eiv){ const u8 iv_size_in_bits = LILI2_IV_SIZE * BITS_IN_WORD; u8 ivl = iv_length; u8 i; if (iv_length > iv_size_in_bits) { /* case d*/ ivl = iv_size_in_bits; } if (ivl == iv_size_in_bits){ /* case a */ for (i = 0; i < LILI2_IV_SIZE; i++) { eiv[i] = iv[i]; } } else if ((ivl % BITS_IN_WORD) == 0) { /* case c */ u8 eiv_length = 0; u8 index; do { for (index = 0; index < (iv_length / BITS_IN_WORD); index++) { eiv[eiv_length++] = iv[index]; if (eiv_length == LILI2_IV_SIZE) { break; } } } while (eiv_length < LILI2_IV_SIZE); } else { u8 dst_word = 0; u8 dst_bit = 0; u8 i; while (dst_word < LILI2_IV_SIZE) { for (i = iv_length; i > 0; i--) { eiv[dst_word] <<= 1; eiv[dst_word] |= GET_BIT(iv, iv_length, (i - 1)); dst_bit++; if (dst_bit == BITS_IN_WORD) { dst_bit = 0; dst_word++; } if (dst_word == LILI2_IV_SIZE) { break; } } } }}#define KEYSTREAM_BYTES 32#include <stdio.h>/*-----------------------* * Usage model * *-----------------------*/int main(){ u8 key[] = { 0xFE, 0x01, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xFE, 0x02, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE }; u8 iv[] = { 0x87}; LILI2Ctx ctx; u8 keystream[KEYSTREAM_BYTES]; u32 keystream_len = KEYSTREAM_BYTES * 8; u32 keystream_bits_generated = 0; u32 i = 0; u8 status = lili2_key_init(&ctx, key, iv, 7); if (status != LILI2_INITIALIZATION_OK) { fprintf(stderr, "Key initialization error. Please rekey cipher"); return status; } keystream_bits_generated = lili2_keystream(&ctx, keystream, keystream_len); if (keystream_bits_generated != keystream_len) { fprintf(stderr, "Error: generated %u bits but expected %u\n", keystream_bits_generated, keystream_len); } fprintf(stdout, "Generating %d bits of keystream\n", keystream_bits_generated);; while (i++ < (keystream_bits_generated / 8)){ fprintf(stdout, "%02X", keystream[i]); } if (keystream_bits_generated % 8) { fprintf(stdout, "%02X", keystream[i]); } fprintf(stdout, "\n"); return 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -