⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lili.c

📁 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 + -