idea.cpp

来自「JdonFramework need above jdk 1.4.0 This」· C++ 代码 · 共 275 行

CPP
275
字号
/*_############################################################################  _##   _##  idea.cpp    _##  _##  SNMP++v3.2.21a  _##  -----------------------------------------------  _##  Copyright (c) 2001-2006 Jochen Katz, Frank Fock  _##  _##  This software is based on SNMP++2.6 from Hewlett Packard:  _##    _##    Copyright (c) 1996  _##    Hewlett-Packard Company  _##    _##  ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.  _##  Permission to use, copy, modify, distribute and/or sell this software   _##  and/or its documentation is hereby granted without fee. User agrees   _##  to display the above copyright notice and this license notice in all   _##  copies of the software and any documentation of the software. User   _##  agrees to assume all liability for the use of the software;   _##  Hewlett-Packard and Jochen Katz make no representations about the   _##  suitability of this software for any purpose. It is provided   _##  "AS-IS" without warranty of any kind, either express or implied. User   _##  hereby grants a royalty-free license to any and all derivatives based  _##  upon this software code base.   _##    _##  Stuttgart, Germany, Tue Nov 21 22:12:16 CET 2006   _##    _##########################################################################*/char idea_cpp_version[]="#(@) SNMP++ $Id: idea.cpp,v 1.4 2004/03/03 23:11:21 katz Exp $";/*idea.cAuthor: Tatu Ylonen <ylo@cs.hut.fi>Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland                   All rights reservedCreated: Sun Jun 25 02:59:39 1995 yloThis code is based on Xuejia Lai: On the Design and Security of BlockCiphers, ETH Series in Information Processing, vol. 1, Hartung-GorreVerlag, Konstanz, Switzerland, 1992.  Another source was BruceSchneier: Applied Cryptography, John Wiley & Sons, 1994.The IDEA mathematical formula may be covered by one or more of thefollowing patents: PCT/CH91/00117, EP 0 482 154 B1, US Pat. 5,214,703.*///#include "snmp_pp/includes.h"//#include "snmp_pp/getput.h"#include "snmp_pp/idea.h"#include <string.h>#ifdef SNMP_PP_NAMESPACEnamespace Snmp_pp {#endif#ifdef _USE_IDEA/* Sets idea key for encryption. */void idea_set_key(IDEAContext *c, const unsigned char key[16]){  int i;  word16 *keys;  /* Get pointer to the keys. */  keys = c->key_schedule;  /* Keys for the first round are directly taken from the user-supplied key. */  for (i = 0; i < 8; i++)    keys[i] = (word16)GET_16BIT(key + 2 * i);  /* Each round uses the key of the previous key, rotated to the left by 25     bits.  The last four keys (output transform) are the first four keys     from what would be the ninth round. */  for (i = 8; i < 52; i++)    {      if ((i & 7) == 0)	keys += 8;      keys[i & 7] = ((keys[((i + 1) & 7) - 8] << 9) |		     (keys[((i + 2) & 7) - 8] >> 7)) & 0xffff;    }}/* Destroys any sensitive data in the context. */void idea_destroy_context(IDEAContext *c){  memset(&c, 0, sizeof(c));}/* Performs the "multiplication" operation of IDEA: returns a*b mod 65537,   where a and b are first converted to 65536 if they are zero, and result   65536 is converted to zero.  Both inputs should be less than 65536.   Only the lower 16 bits of result are significant; other bits are garbage.   */static inline word32 mulop(word32 a, word32 b){  word32 ab = a * b;  if (ab != 0)    {      word32 lo = ab & 0xffff;      word32 hi = (ab >> 16) & 0xffff;      return (lo - hi) + (lo < hi);    }  if (a == 0)    return 1 - b;  return  1 - a;}/* Performs the IDEA cipher transform on a block of data. */void idea_transform(IDEAContext *c, word32 l, word32 r, word32 *output){  unsigned int round;  word16 *keys;  word32 t1, t2, x1, x2, x3, x4;  keys = c->key_schedule;  x1 = l >> 16;  x2 = l;  x3 = r >> 16;  x4 = r;  for (round = 0; round < 8; round++)    {      x1 = mulop(x1 & 0xffff, keys[0]);      x3 = x3 + keys[2];      x4 = mulop(x4 & 0xffff, keys[3]);      x2 = x2 + keys[1];      t1 = x1 ^ x3;      t2 = x2 ^ x4;      t1 = mulop(t1 & 0xffff, keys[4]);      t2 = t1 + t2;      t2 = mulop(t2 & 0xffff, keys[5]);      t1 = t1 + t2;      x1 = x1 ^ t2;      x4 = x4 ^ t1;      t1 = t1 ^ x2;      x2 = t2 ^ x3;      x3 = t1;      keys += 6;    }  x1 = mulop(x1 & 0xffff, keys[0]);  x3 = (x2 + keys[2]) & 0xffff;  x2 = t1 + keys[1]; /* t1 == old x3 */  x4 = mulop(x4 & 0xffff, keys[3]);  output[0] = (x1 << 16) | (x2 & 0xffff);  output[1] = (x3 << 16) | (x4 & 0xffff);}/* Encrypts len bytes from src to dest in CFB mode.  Len need not be a multiple   of 8; if it is not, iv at return will contain garbage.   Otherwise, iv will be modified at end to a value suitable for continuing   encryption. */void idea_cfb_encrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,		      const unsigned char *src, unsigned int len){  word32 iv0, iv1, out[2];  unsigned int i;  iv0 = GET_32BIT(iv);  iv1 = GET_32BIT(iv + 4);  for (i = 0; i < len; i += 8)    {      idea_transform(c, iv0, iv1, out);      iv0 = out[0] ^ GET_32BIT(src + i);      iv1 = out[1] ^ GET_32BIT(src + i + 4);      if (i + 8 <= len)	{	  PUT_32BIT(dest + i, iv0);	  PUT_32BIT(dest + i + 4, iv1);	}      else	{	  switch (len - i)	    {	    case 7:	      dest[i + 6] = iv1 >> 8;	      /*FALLTHROUGH*/	    case 6:	      dest[i + 5] = iv1 >> 16;	      /*FALLTHROUGH*/	    case 5:	      dest[i + 4] = iv1 >> 24;	      /*FALLTHROUGH*/	    case 4:	      dest[i + 3] = iv0;	      /*FALLTHROUGH*/	    case 3:	      dest[i + 2] = iv0 >> 8;	      /*FALLTHROUGH*/	    case 2:	      dest[i + 1] = iv0 >> 16;	      /*FALLTHROUGH*/	    case 1:	      dest[i] = iv0 >> 24;	      /*FALLTHROUGH*/	    }	}    }  PUT_32BIT(iv, iv0);  PUT_32BIT(iv + 4, iv1);}/* Decrypts len bytes from src to dest in CFB mode.  Len need not be a multiple   of 8; if it is not, iv at return will contain garbage.   Otherwise, iv will be modified at end to a value suitable for continuing   decryption. */void idea_cfb_decrypt(IDEAContext *c, unsigned char *iv, unsigned char *dest,		      const unsigned char *src, unsigned int len){  word32 iv0, iv1, out[2], plain0, plain1;  unsigned int i;  iv0 = GET_32BIT(iv);  iv1 = GET_32BIT(iv + 4);  for (i = 0; i < len; i += 8)    {      idea_transform(c, iv0, iv1, out);      iv0 = GET_32BIT(src + i);      iv1 = GET_32BIT(src + i + 4);      plain0 = out[0] ^ iv0;      plain1 = out[1] ^ iv1;      if (i + 8 <= len)	{	  PUT_32BIT(dest + i, plain0);	  PUT_32BIT(dest + i + 4, plain1);	}      else	{	  switch (len - i)	    {	    case 7:	      dest[i + 6] = plain1 >> 8;	      /*FALLTHROUGH*/	    case 6:	      dest[i + 5] = plain1 >> 16;	      /*FALLTHROUGH*/	    case 5:	      dest[i + 4] = plain1 >> 24;	      /*FALLTHROUGH*/	    case 4:	      dest[i + 3] = plain0;	      /*FALLTHROUGH*/	    case 3:	      dest[i + 2] = plain0 >> 8;	      /*FALLTHROUGH*/	    case 2:	      dest[i + 1] = plain0 >> 16;	      /*FALLTHROUGH*/	    case 1:	      dest[i] = plain0 >> 24;	      /*FALLTHROUGH*/	    }	}    }  PUT_32BIT(iv, iv0);  PUT_32BIT(iv + 4, iv1);}#endif#ifdef SNMP_PP_NAMESPACE}; // end of namespace Snmp_pp#endif 

⌨️ 快捷键说明

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