whirlpool/whirlpool_add.c

Go to the documentation of this file.
00001 // Copyright (C) 2006-2007 Benedikt Böhm <hollow@gentoo.org>
00002 //
00003 // The Whirlpool algorithm was developed by
00004 //                Paulo S. L. M. Barreto <pbarreto@scopus.com.br> and
00005 //                Vincent Rijmen <vincent.rijmen@cryptomathic.com>
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // This program is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with this program; if not, write to the Free Software
00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00020 
00021 #include "whirlpool.h"
00022 
00023 void whirlpool_add(whirlpool_t * const context,
00024                 const unsigned char * const src, unsigned long srcbits)
00025 {
00026         int i;
00027         uint32_t b, carry;
00028 
00029         /* index of leftmost source uint8_t containing data (1 to 8 bits). */
00030         int srcpos = 0;
00031 
00032         int gap      = (8 - ((int)srcbits & 7)) & 7; /* space on src[srcpos]. */
00033         int rem      = context->bits & 7; /* occupied bits on buf[pos]. */
00034 
00035         uint8_t *buf = context->buf;
00036         uint8_t *len = context->len;
00037         int bits     = context->bits;
00038         int pos      = context->pos;
00039 
00040         /* tally the length of the added data */
00041         uint64_t value = srcbits;
00042 
00043         for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != 0ULL); i--) {
00044                 carry += len[i] + ((uint32_t)value & 0xff);
00045                 len[i] = (uint8_t)carry;
00046                 carry >>= 8;
00047                 value >>= 8;
00048         }
00049 
00050         /* process data in chunks of 8 bits */
00051         while (srcbits > 8) {
00052                 /* take a byte from the source */
00053                 b = ((src[srcpos] << gap) & 0xff) |
00054                                 ((src[srcpos + 1] & 0xff) >> (8 - gap));
00055 
00056                 /* process this byte */
00057                 buf[pos++] |= (uint8_t)(b >> rem);
00058                 bits += 8 - rem; /* bits = 8*pos; */
00059 
00060                 if (bits == DIGESTBITS) {
00061                         /* process data block */
00062                         whirlpool_transform(context);
00063 
00064                         /* reset buf */
00065                         bits = pos = 0;
00066                 }
00067 
00068                 buf[pos] = b << (8 - rem);
00069                 bits += rem;
00070 
00071                 /* proceed to remaining data */
00072                 srcbits -= 8;
00073                 srcpos++;
00074         }
00075 
00076         /* now 0 <= srcbits <= 8;
00077          * furthermore, all data (if any is left) is in src[srcpos].
00078          */
00079         if (srcbits > 0) {
00080                 b = (src[srcpos] << gap) & 0xff; /* bits are left-justified on b. */
00081 
00082                 /* process the remaining bits */
00083                 buf[pos] |= b >> rem;
00084         }
00085 
00086         else
00087                 b = 0;
00088 
00089         /* all remaining data fits on buf[pos],
00090          * and there still remains some space.
00091          */
00092         if (rem + srcbits < 8)
00093                 bits += srcbits;
00094 
00095         else {
00096                 /* buf[pos] is full */
00097                 pos++;
00098                 bits += 8 - rem; /* bits = 8*pos; */
00099                 srcbits -= 8 - rem;
00100 
00101                 /* now 0 <= srcbits < 8;
00102                  * furthermore, all data (if any is left) is in src[srcpos].
00103                  */
00104                 if (bits == DIGESTBITS) {
00105                         /* process data block */
00106                         whirlpool_transform(context);
00107 
00108                         /* reset buf */
00109                         bits = pos = 0;
00110                 }
00111 
00112                 buf[pos] = b << (8 - rem);
00113                 bits += (int)srcbits;
00114         }
00115 
00116         context->bits = bits;
00117         context->pos  = pos;
00118 }

Generated on Tue Jun 19 20:38:27 2007 for lucid by  doxygen 1.5.2