whirlpool/whirlpool_add.c

Go to the documentation of this file.
00001 // Copyright 2006 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 modify
00008 // it under the terms of the GNU General Public License as published by
00009 // the Free Software Foundation; either version 2 of the License, or
00010 // (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
00019 // Free Software Foundation, Inc.,
00020 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00021 
00022 #include "whirlpool.h"
00023 
00024 void whirlpool_add(whirlpool_t * const context,
00025                    const unsigned char * const src, unsigned long srcbits)
00026 {
00027         int i;
00028         uint32_t b, carry;
00029         int srcpos = 0; /* index of leftmost source uint8_t containing data (1 to 8 bits). */
00030         
00031         int gap      = (8 - ((int)srcbits & 7)) & 7; /* space on src[srcpos]. */
00032         int rem      = context->bits & 7; /* occupied bits on buf[pos]. */
00033         
00034         uint8_t *buf = context->buf;
00035         uint8_t *len = context->len;
00036         int bits     = context->bits;
00037         int pos      = context->pos;
00038         
00039         /* tally the length of the added data */
00040         uint64_t value = srcbits;
00041         
00042         for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != 0ULL); i--) {
00043                 carry += len[i] + ((uint32_t)value & 0xff);
00044                 len[i] = (uint8_t)carry;
00045                 carry >>= 8;
00046                 value >>= 8;
00047         }
00048         
00049         /* process data in chunks of 8 bits */
00050         while (srcbits > 8) {
00051                 /* take a byte from the source */
00052                 b = ((src[srcpos] << gap) & 0xff) |
00053                                 ((src[srcpos + 1] & 0xff) >> (8 - gap));
00054                 
00055                 /* process this byte */
00056                 buf[pos++] |= (uint8_t)(b >> rem);
00057                 bits += 8 - rem; /* bits = 8*pos; */
00058                 
00059                 if (bits == DIGESTBITS) {
00060                         /* process data block */
00061                         whirlpool_transform(context);
00062                         
00063                         /* reset buf */
00064                         bits = pos = 0;
00065                 }
00066                 
00067                 buf[pos] = b << (8 - rem);
00068                 bits += rem;
00069                 
00070                 /* proceed to remaining data */
00071                 srcbits -= 8;
00072                 srcpos++;
00073         }
00074         
00075         /* now 0 <= srcbits <= 8;
00076          * furthermore, all data (if any is left) is in src[srcpos].
00077          */
00078         if (srcbits > 0) {
00079                 b = (src[srcpos] << gap) & 0xff; /* bits are left-justified on b. */
00080                 
00081                 /* process the remaining bits */
00082                 buf[pos] |= b >> rem;
00083         }
00084         
00085         else
00086                 b = 0;
00087         
00088         /* all remaining data fits on buf[pos],
00089          * and there still remains some space.
00090          */
00091         if (rem + srcbits < 8) 
00092                 bits += srcbits;
00093         
00094         else {
00095                 /* buf[pos] is full */
00096                 pos++;
00097                 bits += 8 - rem; /* bits = 8*pos; */
00098                 srcbits -= 8 - rem;
00099                 
00100                 /* now 0 <= srcbits < 8;
00101                  * furthermore, all data (if any is left) is in src[srcpos].
00102                  */
00103                 if (bits == DIGESTBITS) {
00104                         /* process data block */
00105                         whirlpool_transform(context);
00106                         
00107                         /* reset buf */
00108                         bits = pos = 0;
00109                 }
00110                 
00111                 buf[pos] = b << (8 - rem);
00112                 bits += (int)srcbits;
00113         }
00114         
00115         context->bits = bits;
00116         context->pos  = pos;
00117 }

Generated on Sun Dec 3 17:45:53 2006 for lucid by  doxygen 1.5.1