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

📄 loki97.c

📁 LOKI97加密解密算法,用C语言实现的一种加密解密算法。
💻 C
📖 第 1 页 / 共 3 页
字号:
    return TRUE;}/* * decrypt blocks in CFB1 mode */static int deCFB1(cipherInstance *cipher, keyInstance *key, BYTE *input, 		int inputLen, BYTE *outBuffer){    int i,j,k;			/* assorted loop counters */    int b;			/* bit number being processed in byte */    BYTE msgbit, prev, keybit;	/* current & prev message and stream key bits */    ULONG64 L, R;		/* left and right data blocks */    ULONG64 nR, f_out;    /* get CFB1 input buffer from IV */    L = cipher->IVL; R = cipher->IVR;    /* get ready to process first byte */    b = 7;			/* start with top bit in byte */    *outBuffer = 0;		/* and zero byte in outBuffer */    /* now loop over all bits of input */    for (j = 0; j < inputLen; j++) {        msgbit = (*input >> b) & 01;	/* get next msg bit */	prev = msgbit;			/* and save for shift register update */        if (debuglevel) fprintf(stderr,"%s: deCFB1(%01X,%08X%08X%08X%08X) ", NAME, msgbit, L.l, L.r, R.l, R.r);        if (debuglevel > 1) fprintf(stderr,"\n");        /*  compute all rounds to encrypt current CFB1 buffer */        k = 0;        for (i = 0; i < ROUNDS; i++) {            nR = add64(R, key->SK[k++]);		/* nR = R+SK(k) */            f_out = f(nR, key->SK[k++]);		/* f = f(nR,SK(k+1)) */            nR = add64(nR, key->SK[k++]);		/* nR = nR+SK(k+2) */            R.l = L.l ^ f_out.l; R.r = L.r ^ f_out.r;	/* R = L XOR f */            L = nR;					/* L = nR */            if (debuglevel > 1) fprintf(stderr," L[%02d]=%08X%08X; R[%02d]=%08X%08X; f(SK(%02d))=%08X%08X\n", i+1, L.l, L.r, i+1, R.l, R.r, k-2, f_out.l, f_out.r);        }	/* undo last swap */	L = R; R = nR;	/* now process msgbit by getting stream key bit, XOR in and or to out */	keybit = L.l >> 31;	msgbit ^= keybit;	*outBuffer |= (msgbit << b);        if (debuglevel > 0) fprintf(stderr,"= %01X,%08X%08X%08X%08X\n", msgbit, L.l, L.r, R.l, R.r);	/* and update the CFB1 shift register (input buffer L,R) */	L.l = (L.l << 1) | (L.r >> 31); L.r = (L.r << 1) | (R.l >> 31);	R.l = (R.l << 1) | (R.r >> 31); R.r = (R.r << 1) | prev;	/* and update bit position counter */	b--;	/* and move to next input/output byte if necessary */	if (b<0) { b = 7; input++; outBuffer++; *outBuffer = 0; }    }    /* save new IV value */    cipher->IVL = L; cipher->IVR = R;    return TRUE;}/*  LOKI97 methods *//* ......................................................................... */    /* * f(A,B) = Sb(P(Sa(E(KP(A,hi(B))))),lo(B)) - complex non-linear round function */static ULONG64 f (ULONG64 A, ULONG64 B){    ULONG64	d, e, f;	/* intermediate values in f computation */    register	s;		/* s-box output value */    /*  Intermediate values in the computation are: */    /*    d = KP(A,Br) */    /*    e = P(Sa(d)) */    /*    f = Sb(e,Bl) */    /*  Compute d = KP(A,B), where KP is a keyed permutation used to  */    /*     exchange corresponding bits in 32-bit words [Al,Ar]  */    /*     based on the lower half of B (swap if B bit is 1) */    /*     KP(A,B) = ((Al & ~Br)|(Ar & Br)) | ((Ar & ~Br)|(Al & Br)) */    d.l = ((A.l & ~B.r) | (A.r & B.r));    d.r = ((A.r & ~B.r) | (A.l & B.r));    /*  Compute e = P(Sa(d)) */    /*     mask out each group of 12 bits for E */    /*     then compute first S-box column [S1,S2,S1,S2,S2,S1,S2,S1] */    /*     permuting output through P (with extra shift to build full P) */    s = S1[(d.l>>24 | d.r<<8) & 0x1FFF];  e.l  = P[s].l>>7;  e.r  = P[s].r>>7;    s = S2[(d.l>>16)          &  0x7FF];  e.l |= P[s].l>>6;  e.r |= P[s].r>>6;    s = S1[(d.l>> 8)          & 0x1FFF];  e.l |= P[s].l>>5;  e.r |= P[s].r>>5;    s = S2[ d.l               &  0x7FF];  e.l |= P[s].l>>4;  e.r |= P[s].r>>4;    s = S2[(d.r>>24 | d.l<<8) &  0x7FF];  e.l |= P[s].l>>3;  e.r |= P[s].r>>3;    s = S1[(d.r>>16)          & 0x1FFF];  e.l |= P[s].l>>2;  e.r |= P[s].r>>2;    s = S2[(d.r>> 8)          &  0x7FF];  e.l |= P[s].l>>1;  e.r |= P[s].r>>1;    s = S1[ d.r               & 0x1FFF];  e.l |= P[s].l;     e.r |= P[s].r;    /*  Compute f = Sb(e,B) */    /*     where the second S-box column is [S2,S2,S1,S1,S2,S2,S1,S1] */    /*     for each S, lower bits come from e, upper from upper half of B */    f.l = S2[(((e.l>>24) & 0xFF) | ((B.l>>21) &  0x700))] << 24 |          S2[(((e.l>>16) & 0xFF) | ((B.l>>18) &  0x700))] << 16 |          S1[(((e.l>> 8) & 0xFF) | ((B.l>>13) & 0x1F00))] <<  8 |          S1[(((e.l    ) & 0xFF) | ((B.l>> 8) & 0x1F00))];    f.r = S2[(((e.r>>24) & 0xFF) | ((B.l>> 5) &  0x700))] << 24 |          S2[(((e.r>>16) & 0xFF) | ((B.l>> 2) &  0x700))] << 16 |          S1[(((e.r>> 8) & 0xFF) | ((B.l<< 3) & 0x1F00))] <<  8 |          S1[(( e.r      & 0xFF) | ((B.l<< 8) & 0x1F00))];    if (debuglevel > 3) fprintf(stderr,"%s: f(%08X%08X,%08X%08X) = %08X%08X\n", NAME, A.l, A.r, B.l, B.r, f.l, f.r);    if (debuglevel > 4) fprintf(stderr,"%s:   d=%08X%08X; e=%08X%08X\n", NAME, d.l, d.r, e.l, e.r);    return f;}/*  utility methods *//* ......................................................................... *//* add64(a,b) - fudge 64-bit addition of ULONG64's a and b *//* thanks to Markku-Juhani Saarinen <mjos@ssh.fi> for the nice tips */static ULONG64 add64(ULONG64 a, ULONG64 b){    ULONG64		sum;		/* sum = a + b */    sum.r = a.r + b.r;			/* add lower half */    sum.l = a.l + b.l;			/* add upper half without carry */    if (sum.r < b.r) sum.l++;		/* add carry if needed */    return sum;				/* return resulting sum */}/* sub64(a,b) - fudge 64-bit subtraction of ULONG64's a and b *//* thanks to Markku-Juhani Saarinen <mjos@ssh.fi> for the nice tips */static ULONG64 sub64(ULONG64 a, ULONG64 b){    ULONG64		diff;		/* diff = a + b */    diff.r = a.r - b.r;			/* sub lower 32-bits */    diff.l = a.l - b.l;			/* sub upper 32-bits */    if (diff.r > a.r) diff.l--;		/* sub borrow if needed */    return diff;			/* return resulting diff */}/* Returns a ULONG64 I constructed from a byte array. */static ULONG64 byteToULONG64(BYTE *inp){    ULONG64 I;    I.l  = (*inp++ << 24);    I.l |= (*inp++ << 16);    I.l |= (*inp++ <<  8);    I.l |= *inp++;    I.r  = (*inp++ << 24);    I.r |= (*inp++ << 16);    I.r |= (*inp++ <<  8);    I.r |= *inp++;    return I;}/* Returns a byte array buf constructed by unpacking ULONG64 I. */static BYTE *ULONG64ToBYTE(BYTE *buf, ULONG64 I){    BYTE *sav = buf;    *buf++ = (I.l >> 24);    *buf++ = (I.l >> 16);    *buf++ = (I.l >>  8);    *buf++ = I.l;    *buf++ = (I.r >> 24);    *buf++ = (I.r >> 16);    *buf++ = (I.r >>  8);    *buf++ = I.r;    return sav;}/* Returns a BYTE array from a string of hexadecimal digits. */static BYTE *charToBYTE(BYTE *buf, char *hex, int len){    int i = 0, j = 0;    while (j < len) {        buf[j++] = (BYTE)((fromHex(hex[i++])<<4) | fromHex(hex[i++]));    }    return buf;}/* Returns a ULONG64 I constructed from a string of hexadecimal digits. */static ULONG64 charToULONG64(char *hex){    ULONG64 I;    I.l  = fromHex(*hex++) << 28;    I.l |= fromHex(*hex++) << 24;    I.l |= fromHex(*hex++) << 20;    I.l |= fromHex(*hex++) << 16;    I.l |= fromHex(*hex++) << 12;    I.l |= fromHex(*hex++) <<  8;    I.l |= fromHex(*hex++) <<  4;    I.l |= fromHex(*hex++);    I.r  = fromHex(*hex++) << 28;    I.r |= fromHex(*hex++) << 24;    I.r |= fromHex(*hex++) << 20;    I.r |= fromHex(*hex++) << 16;    I.r |= fromHex(*hex++) << 12;    I.r |= fromHex(*hex++) <<  8;    I.r |= fromHex(*hex++) <<  4;    I.r |= fromHex(*hex++);    return I;}/* Returns number from 0 to 15 corresponding to hex digit ch */static int fromHex (char ch){    if (ch >= '0' && ch <= '9')        return ch - '0';    else if (ch >= 'A' && ch <= 'F')        return ch - 'A' + 10;    else if (ch >= 'a' && ch <= 'f')        return ch - 'a' + 10;    else        return 0;}/* puthex(out, len, f) - display a len byte value out in hex to file f */static int puthex(BYTE *out, int len, FILE *f){    int i;    for(i=0;i<len;i++){        fprintf(f, "%02X",*out++ & 0xff);    }    fputc(' ', f);}/* ......................................................................... *//* * self_test() - Encryption/decryption test using the standard single triple  *    returns true or error code */int self_test(){    int enok = TRUE, deok = TRUE;    char *hexkey = "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F";    char *hexcipher = "75080E359F10FE640144B35C57128DAD";    char *hexIV = "00000000000000000000000000000000";    BYTE	plain[BLOCK_SIZE] =			{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};    BYTE	etemp[BLOCK_SIZE], dtemp[BLOCK_SIZE], cipher[BLOCK_SIZE];    keyInstance		enc_key, dec_key;	/* AES keyInstances */    cipherInstance	loki97_cipher;		/* AES cipherInstance */    int	i, st;    /* construct desired cipher block */    charToBYTE(cipher,hexcipher,sizeof(cipher));    /* Init LOKI97 cipher in ECB mode */    st = cipherInit(&loki97_cipher, MODE_ECB, hexIV); if (st != TRUE) return st;    /* test encrypt */    st = makeKey(&enc_key, DIR_ENCRYPT, 256, hexkey); if (st != TRUE) return st;    fprintf(stderr,"Plaintext is: ");    puthex(plain,16,stderr); fprintf(stderr,"\n");    st = blockEncrypt(&loki97_cipher, &enc_key, plain, sizeof(plain)*8, etemp);    if (st != TRUE) return st;    if (memcmp(etemp, cipher, sizeof(etemp)) != 0) enok = FALSE;    fprintf(stderr,"Test encrypt: "); puthex(etemp,16,stderr);    fprintf(stderr," %s\n", (enok?"GOOD" : "FAILED"));    /* test decrypt */    st = makeKey(&dec_key, DIR_DECRYPT, 256, hexkey); if (st != TRUE) return st;    st = blockDecrypt(&loki97_cipher, &dec_key, etemp, sizeof(etemp)*8, dtemp);    if (st != TRUE) return st;    if (memcmp(dtemp, plain, sizeof(dtemp)) != 0) deok = FALSE;    fprintf(stderr,"Test decrypt: "); puthex(dtemp,16,stderr);    fprintf(stderr," %s\n", (deok?"GOOD" : "FAILED"));    return (enok && deok);	/* return TRUE only if both en & decrypt ok */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -