📄 lili.c
字号:
/*
* lili.c
*
* Lili - A stream cipher for submission to NESSIE (New European Schemes
* for Signature, Integrity, and Encryption).
*
* Authors: Lyta Penna & Andrew Clark
* Information Security Research Centre
* Queensland University of Technology
*
* September 2000
*
*/
#include "nessie.h"
#include "lili.h"
/*
* Set up the initial state of the shift registers.
* Assumes 'key' points to 16 bytes (128 bits) of keying material.
* Initialises LFSRc with the first 39 bits, and LFSRd with the
* remaining 89 bits.
*/
void NESSIEkeysetup(const unsigned char * const key, struct NESSIEstruct * const structpointer)
{
structpointer->LFSRc[1] = key[0] >> 1;
structpointer->LFSRc[0] = key[0] & 0x01;
structpointer->LFSRc[0] <<= 8;
structpointer->LFSRc[0] |= key[1];
structpointer->LFSRc[0] <<= 8;
structpointer->LFSRc[0] |= key[2];
structpointer->LFSRc[0] <<= 8;
structpointer->LFSRc[0] |= key[3];
structpointer->LFSRc[0] <<= 7;
structpointer->LFSRc[0] |= (key[4] >> 1);
structpointer->LFSRd[2] = key[4] & 0x01;
structpointer->LFSRd[2] <<= 8;
structpointer->LFSRd[2] |= key[5];
structpointer->LFSRd[2] <<= 8;
structpointer->LFSRd[2] |= key[6];
structpointer->LFSRd[2] <<= 8;
structpointer->LFSRd[2] |= key[7];
structpointer->LFSRd[1] = key[8];
structpointer->LFSRd[1] <<= 8;
structpointer->LFSRd[1] |= key[9];
structpointer->LFSRd[1] <<= 8;
structpointer->LFSRd[1] |= key[10];
structpointer->LFSRd[1] <<= 8;
structpointer->LFSRd[1] |= key[11];
structpointer->LFSRd[0] = key[12];
structpointer->LFSRd[0] <<= 8;
structpointer->LFSRd[0] |= key[13];
structpointer->LFSRd[0] <<= 8;
structpointer->LFSRd[0] |= key[14];
structpointer->LFSRd[0] <<= 8;
structpointer->LFSRd[0] |= key[15];
}
/*
* Compute the next 8 bits of the keystream.
* Assumes 'keystream' points to a single byte. The 8 bits of keystream
* generated will be written to this byte.
*/
void NESSIEkeystream(struct NESSIEstruct * const structpointer, unsigned char *const keystream)
{
u32 i, j, TToffset;
*keystream = 0;
for (i=0; i<8; i++)
{
/*
* LFSRc: bit positions numbered 0...38, left to right.
* The number of clocks for LFSRd is calculated using bits 12 and 20.
*/
j = ((structpointer->LFSRc[0] & 0x04000000) >> 25) |
((structpointer->LFSRc[0] & 0x00040000) >> 18);
/* Clock LFSRc
* Shift to the left.
*/
structpointer->LFSRc[1] = (structpointer->LFSRc[1] << 1) | (structpointer->LFSRc[0] >> 31);
structpointer->LFSRc[0] <<= 1;
/*
* The primitive polynomial is:
* x^39 + x^35 + x^33 + x^31 + x^17 + x^15 + x^14 + x^2 +1
*/
structpointer->LFSRc[0] |= ((structpointer->LFSRc[1] >> 7) ^
(structpointer->LFSRc[1] >> 3) ^
(structpointer->LFSRc[1] >> 1) ^
(structpointer->LFSRc[0] >> 31) ^
(structpointer->LFSRc[0] >> 17) ^
(structpointer->LFSRc[0] >> 15) ^
(structpointer->LFSRc[0] >> 14) ^
(structpointer->LFSRc[0] >> 2)) & 0x1;
/*
* LFSRd: bit positions numbered 0...88, left to right.
* Extract bits: 0,1,3,7,12,20,30,44,65,80 as inputs to the nonlinear function
* (truth table).
*/
TToffset = ((structpointer->LFSRd[2] & 0x01000000) >> 15) |
((structpointer->LFSRd[2] & 0x00800000) >> 15) |
((structpointer->LFSRd[2] & 0x00200000) >> 14) |
((structpointer->LFSRd[2] & 0x00020000) >> 11) |
((structpointer->LFSRd[2] & 0x00001000) >> 7) |
((structpointer->LFSRd[2] & 0x00000010) ) |
((structpointer->LFSRd[1] & 0x04000000) >> 23) |
((structpointer->LFSRd[1] & 0x00001000) >> 10) |
((structpointer->LFSRd[0] & 0x00800000) >> 22) |
((structpointer->LFSRd[0] & 0x00000100) >> 8);
/* Clock LFSRd j times. */
for (j=j+1; j>0; j--)
{
/* Shift LFSRd left. */
structpointer->LFSRd[2] = (structpointer->LFSRd[2] << 1) | (structpointer->LFSRd[1] >> 31);
structpointer->LFSRd[1] = (structpointer->LFSRd[1] << 1) | (structpointer->LFSRd[0] >> 31);
structpointer->LFSRd[0] = (structpointer->LFSRd[0] << 1);
/*
* The primitive polynomial is:
* x^89 + x^83 + x^80 + x^55 + x^53 + x^42 + x^39 + x + 1
*/
structpointer->LFSRd[0] |= ((structpointer->LFSRd[2] >> 25) ^
(structpointer->LFSRd[2] >> 19) ^
(structpointer->LFSRd[2] >> 16) ^
(structpointer->LFSRd[1] >> 23) ^
(structpointer->LFSRd[1] >> 21) ^
(structpointer->LFSRd[1] >> 10) ^
(structpointer->LFSRd[1] >> 7) ^
(structpointer->LFSRd[0] >> 1)) & 0x1;
}
/* Determine key bit from the truth table using tap setting bits */
*keystream = (*keystream << 1) | TT[TToffset];
}
}
/*
* Exclusive-or the plaintext with the keystream to obtain the ciphertext.
* Encrypts 1 byte per call.
*/
void NESSIEoutput(const unsigned char * const keystream, const unsigned char * const plaintext, unsigned char * const ciphertext)
{
*ciphertext = *plaintext ^ *keystream;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -