whirlpool-algorithm.c.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:15k
源码类别:

外挂编程

开发平台:

Windows_Unix

  1. /**
  2.  * The Whirlpool hashing function.
  3.  *
  4.  * The Whirlpool algorithm was developed by
  5.  * Paulo S. L. M. Barreto and Vincent Rijmen.
  6.  *
  7.  * See
  8.  *      P.S.L.M. Barreto, V. Rijmen,
  9.  *      ``The Whirlpool hashing function,''
  10.  *      NESSIE submission, 2000 (tweaked version, 2001),
  11.  *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
  12.  *
  13.  * @version 3.0 (2003.03.12)
  14.  *
  15.  * Modified for use in this software package.
  16.  */
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <limits.h>
  20. #include "whirlpool-algorithm.h"
  21. #include "whirlpool-portability.h"
  22. #include "whirlpool-constants.h"
  23. #ifdef __cplusplus
  24. extern "C" {
  25. #endif
  26. /**
  27.  * The core Whirlpool transform.
  28.  */
  29. static void
  30. processBuffer(WP_Struct * const structpointer) {
  31.     int i, r;
  32.     u64 K[8];        /* the round key */
  33.     u64 block[8];    /* mu(buffer) */
  34.     u64 state[8];    /* the cipher state */
  35.     u64 L[8];
  36.     u8 *buffer = structpointer->buffer;
  37.     /*
  38.      * map the buffer to a block:
  39.      */
  40.     for (i = 0; i < 8; i++, buffer += 8) {
  41.         block[i] =
  42.             (((u64)buffer[0]        ) << 56) ^
  43.             (((u64)buffer[1] & 0xffL) << 48) ^
  44.             (((u64)buffer[2] & 0xffL) << 40) ^
  45.             (((u64)buffer[3] & 0xffL) << 32) ^
  46.             (((u64)buffer[4] & 0xffL) << 24) ^
  47.             (((u64)buffer[5] & 0xffL) << 16) ^
  48.             (((u64)buffer[6] & 0xffL) <<  8) ^
  49.             (((u64)buffer[7] & 0xffL)      );
  50.     }
  51.     /*
  52.      * compute and apply K^0 to the cipher state:
  53.      */
  54.     state[0] = block[0] ^ (K[0] = structpointer->hash[0]);
  55.     state[1] = block[1] ^ (K[1] = structpointer->hash[1]);
  56.     state[2] = block[2] ^ (K[2] = structpointer->hash[2]);
  57.     state[3] = block[3] ^ (K[3] = structpointer->hash[3]);
  58.     state[4] = block[4] ^ (K[4] = structpointer->hash[4]);
  59.     state[5] = block[5] ^ (K[5] = structpointer->hash[5]);
  60.     state[6] = block[6] ^ (K[6] = structpointer->hash[6]);
  61.     state[7] = block[7] ^ (K[7] = structpointer->hash[7]);
  62.     /*
  63.      * iterate over all rounds:
  64.      */
  65.     for (r = 1; r <= R; r++) {
  66.         /*
  67.          * compute K^r from K^{r-1}:
  68.          */
  69.         L[0] =
  70.             C0[(int)(K[0] >> 56)       ] ^
  71.             C1[(int)(K[7] >> 48) & 0xff] ^
  72.             C2[(int)(K[6] >> 40) & 0xff] ^
  73.             C3[(int)(K[5] >> 32) & 0xff] ^
  74.             C4[(int)(K[4] >> 24) & 0xff] ^
  75.             C5[(int)(K[3] >> 16) & 0xff] ^
  76.             C6[(int)(K[2] >>  8) & 0xff] ^
  77.             C7[(int)(K[1]      ) & 0xff] ^
  78.             rc[r];
  79.         L[1] =
  80.             C0[(int)(K[1] >> 56)       ] ^
  81.             C1[(int)(K[0] >> 48) & 0xff] ^
  82.             C2[(int)(K[7] >> 40) & 0xff] ^
  83.             C3[(int)(K[6] >> 32) & 0xff] ^
  84.             C4[(int)(K[5] >> 24) & 0xff] ^
  85.             C5[(int)(K[4] >> 16) & 0xff] ^
  86.             C6[(int)(K[3] >>  8) & 0xff] ^
  87.             C7[(int)(K[2]      ) & 0xff];
  88.         L[2] =
  89.             C0[(int)(K[2] >> 56)       ] ^
  90.             C1[(int)(K[1] >> 48) & 0xff] ^
  91.             C2[(int)(K[0] >> 40) & 0xff] ^
  92.             C3[(int)(K[7] >> 32) & 0xff] ^
  93.             C4[(int)(K[6] >> 24) & 0xff] ^
  94.             C5[(int)(K[5] >> 16) & 0xff] ^
  95.             C6[(int)(K[4] >>  8) & 0xff] ^
  96.             C7[(int)(K[3]      ) & 0xff];
  97.         L[3] =
  98.             C0[(int)(K[3] >> 56)       ] ^
  99.             C1[(int)(K[2] >> 48) & 0xff] ^
  100.             C2[(int)(K[1] >> 40) & 0xff] ^
  101.             C3[(int)(K[0] >> 32) & 0xff] ^
  102.             C4[(int)(K[7] >> 24) & 0xff] ^
  103.             C5[(int)(K[6] >> 16) & 0xff] ^
  104.             C6[(int)(K[5] >>  8) & 0xff] ^
  105.             C7[(int)(K[4]      ) & 0xff];
  106.         L[4] =
  107.             C0[(int)(K[4] >> 56)       ] ^
  108.             C1[(int)(K[3] >> 48) & 0xff] ^
  109.             C2[(int)(K[2] >> 40) & 0xff] ^
  110.             C3[(int)(K[1] >> 32) & 0xff] ^
  111.             C4[(int)(K[0] >> 24) & 0xff] ^
  112.             C5[(int)(K[7] >> 16) & 0xff] ^
  113.             C6[(int)(K[6] >>  8) & 0xff] ^
  114.             C7[(int)(K[5]      ) & 0xff];
  115.         L[5] =
  116.             C0[(int)(K[5] >> 56)       ] ^
  117.             C1[(int)(K[4] >> 48) & 0xff] ^
  118.             C2[(int)(K[3] >> 40) & 0xff] ^
  119.             C3[(int)(K[2] >> 32) & 0xff] ^
  120.             C4[(int)(K[1] >> 24) & 0xff] ^
  121.             C5[(int)(K[0] >> 16) & 0xff] ^
  122.             C6[(int)(K[7] >>  8) & 0xff] ^
  123.             C7[(int)(K[6]      ) & 0xff];
  124.         L[6] =
  125.             C0[(int)(K[6] >> 56)       ] ^
  126.             C1[(int)(K[5] >> 48) & 0xff] ^
  127.             C2[(int)(K[4] >> 40) & 0xff] ^
  128.             C3[(int)(K[3] >> 32) & 0xff] ^
  129.             C4[(int)(K[2] >> 24) & 0xff] ^
  130.             C5[(int)(K[1] >> 16) & 0xff] ^
  131.             C6[(int)(K[0] >>  8) & 0xff] ^
  132.             C7[(int)(K[7]      ) & 0xff];
  133.         L[7] =
  134.             C0[(int)(K[7] >> 56)       ] ^
  135.             C1[(int)(K[6] >> 48) & 0xff] ^
  136.             C2[(int)(K[5] >> 40) & 0xff] ^
  137.             C3[(int)(K[4] >> 32) & 0xff] ^
  138.             C4[(int)(K[3] >> 24) & 0xff] ^
  139.             C5[(int)(K[2] >> 16) & 0xff] ^
  140.             C6[(int)(K[1] >>  8) & 0xff] ^
  141.             C7[(int)(K[0]      ) & 0xff];
  142.         K[0] = L[0];
  143.         K[1] = L[1];
  144.         K[2] = L[2];
  145.         K[3] = L[3];
  146.         K[4] = L[4];
  147.         K[5] = L[5];
  148.         K[6] = L[6];
  149.         K[7] = L[7];
  150.         /*
  151.          * apply the r-th round transformation:
  152.          */
  153.         L[0] =
  154.             C0[(int)(state[0] >> 56)       ] ^
  155.             C1[(int)(state[7] >> 48) & 0xff] ^
  156.             C2[(int)(state[6] >> 40) & 0xff] ^
  157.             C3[(int)(state[5] >> 32) & 0xff] ^
  158.             C4[(int)(state[4] >> 24) & 0xff] ^
  159.             C5[(int)(state[3] >> 16) & 0xff] ^
  160.             C6[(int)(state[2] >>  8) & 0xff] ^
  161.             C7[(int)(state[1]      ) & 0xff] ^
  162.             K[0];
  163.         L[1] =
  164.             C0[(int)(state[1] >> 56)       ] ^
  165.             C1[(int)(state[0] >> 48) & 0xff] ^
  166.             C2[(int)(state[7] >> 40) & 0xff] ^
  167.             C3[(int)(state[6] >> 32) & 0xff] ^
  168.             C4[(int)(state[5] >> 24) & 0xff] ^
  169.             C5[(int)(state[4] >> 16) & 0xff] ^
  170.             C6[(int)(state[3] >>  8) & 0xff] ^
  171.             C7[(int)(state[2]      ) & 0xff] ^
  172.             K[1];
  173.         L[2] =
  174.             C0[(int)(state[2] >> 56)       ] ^
  175.             C1[(int)(state[1] >> 48) & 0xff] ^
  176.             C2[(int)(state[0] >> 40) & 0xff] ^
  177.             C3[(int)(state[7] >> 32) & 0xff] ^
  178.             C4[(int)(state[6] >> 24) & 0xff] ^
  179.             C5[(int)(state[5] >> 16) & 0xff] ^
  180.             C6[(int)(state[4] >>  8) & 0xff] ^
  181.             C7[(int)(state[3]      ) & 0xff] ^
  182.             K[2];
  183.         L[3] =
  184.             C0[(int)(state[3] >> 56)       ] ^
  185.             C1[(int)(state[2] >> 48) & 0xff] ^
  186.             C2[(int)(state[1] >> 40) & 0xff] ^
  187.             C3[(int)(state[0] >> 32) & 0xff] ^
  188.             C4[(int)(state[7] >> 24) & 0xff] ^
  189.             C5[(int)(state[6] >> 16) & 0xff] ^
  190.             C6[(int)(state[5] >>  8) & 0xff] ^
  191.             C7[(int)(state[4]      ) & 0xff] ^
  192.             K[3];
  193.         L[4] =
  194.             C0[(int)(state[4] >> 56)       ] ^
  195.             C1[(int)(state[3] >> 48) & 0xff] ^
  196.             C2[(int)(state[2] >> 40) & 0xff] ^
  197.             C3[(int)(state[1] >> 32) & 0xff] ^
  198.             C4[(int)(state[0] >> 24) & 0xff] ^
  199.             C5[(int)(state[7] >> 16) & 0xff] ^
  200.             C6[(int)(state[6] >>  8) & 0xff] ^
  201.             C7[(int)(state[5]      ) & 0xff] ^
  202.             K[4];
  203.         L[5] =
  204.             C0[(int)(state[5] >> 56)       ] ^
  205.             C1[(int)(state[4] >> 48) & 0xff] ^
  206.             C2[(int)(state[3] >> 40) & 0xff] ^
  207.             C3[(int)(state[2] >> 32) & 0xff] ^
  208.             C4[(int)(state[1] >> 24) & 0xff] ^
  209.             C5[(int)(state[0] >> 16) & 0xff] ^
  210.             C6[(int)(state[7] >>  8) & 0xff] ^
  211.             C7[(int)(state[6]      ) & 0xff] ^
  212.             K[5];
  213.         L[6] =
  214.             C0[(int)(state[6] >> 56)       ] ^
  215.             C1[(int)(state[5] >> 48) & 0xff] ^
  216.             C2[(int)(state[4] >> 40) & 0xff] ^
  217.             C3[(int)(state[3] >> 32) & 0xff] ^
  218.             C4[(int)(state[2] >> 24) & 0xff] ^
  219.             C5[(int)(state[1] >> 16) & 0xff] ^
  220.             C6[(int)(state[0] >>  8) & 0xff] ^
  221.             C7[(int)(state[7]      ) & 0xff] ^
  222.             K[6];
  223.         L[7] =
  224.             C0[(int)(state[7] >> 56)       ] ^
  225.             C1[(int)(state[6] >> 48) & 0xff] ^
  226.             C2[(int)(state[5] >> 40) & 0xff] ^
  227.             C3[(int)(state[4] >> 32) & 0xff] ^
  228.             C4[(int)(state[3] >> 24) & 0xff] ^
  229.             C5[(int)(state[2] >> 16) & 0xff] ^
  230.             C6[(int)(state[1] >>  8) & 0xff] ^
  231.             C7[(int)(state[0]      ) & 0xff] ^
  232.             K[7];
  233.         state[0] = L[0];
  234.         state[1] = L[1];
  235.         state[2] = L[2];
  236.         state[3] = L[3];
  237.         state[4] = L[4];
  238.         state[5] = L[5];
  239.         state[6] = L[6];
  240.         state[7] = L[7];
  241.     }
  242.     /*
  243.      * apply the Miyaguchi-Preneel compression function:
  244.      */
  245.     structpointer->hash[0] ^= state[0] ^ block[0];
  246.     structpointer->hash[1] ^= state[1] ^ block[1];
  247.     structpointer->hash[2] ^= state[2] ^ block[2];
  248.     structpointer->hash[3] ^= state[3] ^ block[3];
  249.     structpointer->hash[4] ^= state[4] ^ block[4];
  250.     structpointer->hash[5] ^= state[5] ^ block[5];
  251.     structpointer->hash[6] ^= state[6] ^ block[6];
  252.     structpointer->hash[7] ^= state[7] ^ block[7];
  253. }
  254. WP_Struct *
  255. WP_Create() {
  256. WP_Struct *wp;
  257. wp = (WP_Struct *) malloc(sizeof(WP_Struct));
  258. if (wp != NULL) {
  259. WP_Init(wp);
  260. }
  261. return wp;
  262. }
  263. void
  264. WP_Init(WP_Struct *wp) {
  265. int i;
  266. memset(wp->bitLength, 0, 32);
  267. wp->bufferBits = wp->bufferPos = 0;
  268. wp->buffer[0] = 0; /* it's only necessary to cleanup buffer[bufferPos] */
  269. for (i = 0; i < 8; i++) {
  270. wp->hash[i] = 0L; /* initial value */
  271. }
  272. }
  273. void WP_Add(const unsigned char * const source,
  274.                unsigned long sourceBits,
  275.                WP_Struct * const structpointer) {
  276.     /*
  277.                        sourcePos
  278.                        |
  279.                        +-------+-------+-------
  280.                           ||||||||||||||||||||| source
  281.                        +-------+-------+-------
  282.     +-------+-------+-------+-------+-------+-------
  283.     ||||||||||||||||||||||                           buffer
  284.     +-------+-------+-------+-------+-------+-------
  285.                     |
  286.                     bufferPos
  287.     */
  288.     int sourcePos    = 0; /* index of leftmost source u8 containing data (1 to 8 bits). */
  289.     int sourceGap    = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */
  290.     int bufferRem    = structpointer->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */
  291.     int i;
  292.     u32 b, carry;
  293.     u8 *buffer       = structpointer->buffer;
  294.     u8 *bitLength    = structpointer->bitLength;
  295.     int bufferBits   = structpointer->bufferBits;
  296.     int bufferPos    = structpointer->bufferPos;
  297.     /*
  298.      * This method maintains the invariant: bufferBits < DIGESTBITS
  299.      */
  300.     /*
  301.      * tally the length of the added data:
  302.      */
  303.     u64 value = sourceBits;
  304.     for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != LL(0)); i--) {
  305.         carry += bitLength[i] + ((u32)value & 0xff);
  306.         bitLength[i] = (u8)carry;
  307.         carry >>= 8;
  308.         value >>= 8;
  309.     }
  310.     /*
  311.      * process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks):
  312.      */
  313.     while (sourceBits > 8) {
  314.         /* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */
  315.         /*
  316.          * take a byte from the source:
  317.          */
  318.         b = ((source[sourcePos] << sourceGap) & 0xff) |
  319.             ((source[sourcePos + 1] & 0xff) >> (8 - sourceGap));
  320.         /*
  321.          * process this byte:
  322.          */
  323.         buffer[bufferPos++] |= (u8)(b >> bufferRem);
  324.         bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
  325.         if (bufferBits == DIGESTBITS) {
  326.             /*
  327.              * process data block:
  328.              */
  329.             processBuffer(structpointer);
  330.             /*
  331.              * reset buffer:
  332.              */
  333.             bufferBits = bufferPos = 0;
  334.         }
  335.         buffer[bufferPos] = b << (8 - bufferRem);
  336.         bufferBits += bufferRem;
  337.         /*
  338.          * proceed to remaining data:
  339.          */
  340.         sourceBits -= 8;
  341.         sourcePos++;
  342.     }
  343.     /* now 0 <= sourceBits <= 8;
  344.      * furthermore, all data (if any is left) is in source[sourcePos].
  345.      */
  346.     if (sourceBits > 0) {
  347.         b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */
  348.         /*
  349.          * process the remaining bits:
  350.          */
  351.         buffer[bufferPos] |= b >> bufferRem;
  352.     } else {
  353.         b = 0;
  354.     }
  355.     if (bufferRem + sourceBits < 8) {
  356.         /*
  357.          * all remaining data fits on buffer[bufferPos],
  358.          * and there still remains some space.
  359.          */
  360.         bufferBits += sourceBits;
  361.     } else {
  362.         /*
  363.          * buffer[bufferPos] is full:
  364.          */
  365.         bufferPos++;
  366.         bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */
  367.         sourceBits -= 8 - bufferRem;
  368.         /* now 0 <= sourceBits < 8;
  369.          * furthermore, all data (if any is left) is in source[sourcePos].
  370.          */
  371.         if (bufferBits == DIGESTBITS) {
  372.             /*
  373.              * process data block:
  374.              */
  375.             processBuffer(structpointer);
  376.             /*
  377.              * reset buffer:
  378.              */
  379.             bufferBits = bufferPos = 0;
  380.         }
  381.         buffer[bufferPos] = b << (8 - bufferRem);
  382.         bufferBits += (int)sourceBits;
  383.     }
  384.     structpointer->bufferBits   = bufferBits;
  385.     structpointer->bufferPos    = bufferPos;
  386. }
  387. void WP_Finalize(WP_Struct * const structpointer,
  388.                     unsigned char * const result) {
  389.     int i;
  390.     u8 *buffer      = structpointer->buffer;
  391.     u8 *bitLength   = structpointer->bitLength;
  392.     int bufferBits  = structpointer->bufferBits;
  393.     int bufferPos   = structpointer->bufferPos;
  394.     u8 *digest      = result;
  395.     /*
  396.      * This method uses the invariant: bufferBits < DIGESTBITS
  397.      */
  398.     /*
  399.      * append a '1'-bit:
  400.      */
  401.     buffer[bufferPos] |= 0x80U >> (bufferBits & 7);
  402.     bufferPos++; /* all remaining bits on the current u8 are set to zero. */
  403.     /*
  404.      * pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits:
  405.      */
  406.     if (bufferPos > WBLOCKBYTES - LENGTHBYTES) {
  407.         if (bufferPos < WBLOCKBYTES) {
  408.             memset(&buffer[bufferPos], 0, WBLOCKBYTES - bufferPos);
  409.         }
  410.         /*
  411.          * process data block:
  412.          */
  413.         processBuffer(structpointer);
  414.         /*
  415.          * reset buffer:
  416.          */
  417.         bufferPos = 0;
  418.     }
  419.     if (bufferPos < WBLOCKBYTES - LENGTHBYTES) {
  420.         memset(&buffer[bufferPos], 0, (WBLOCKBYTES - LENGTHBYTES) - bufferPos);
  421.     }
  422.     bufferPos = WBLOCKBYTES - LENGTHBYTES;
  423.     /*
  424.      * append bit length of hashed data:
  425.      */
  426.     memcpy(&buffer[WBLOCKBYTES - LENGTHBYTES], bitLength, LENGTHBYTES);
  427.     /*
  428.      * process data block:
  429.      */
  430.     processBuffer(structpointer);
  431.     /*
  432.      * return the completed message digest:
  433.      */
  434.     for (i = 0; i < DIGESTBYTES/8; i++) {
  435.         digest[0] = (u8)(structpointer->hash[i] >> 56);
  436.         digest[1] = (u8)(structpointer->hash[i] >> 48);
  437.         digest[2] = (u8)(structpointer->hash[i] >> 40);
  438.         digest[3] = (u8)(structpointer->hash[i] >> 32);
  439.         digest[4] = (u8)(structpointer->hash[i] >> 24);
  440.         digest[5] = (u8)(structpointer->hash[i] >> 16);
  441.         digest[6] = (u8)(structpointer->hash[i] >>  8);
  442.         digest[7] = (u8)(structpointer->hash[i]      );
  443.         digest += 8;
  444.     }
  445.     structpointer->bufferBits   = bufferBits;
  446.     structpointer->bufferPos    = bufferPos;
  447. }
  448. void
  449. WP_Free(WP_Struct *wp) {
  450. free(wp);
  451. }
  452. #ifdef __cplusplus
  453. }
  454. #endif