sha1.c
changeset 48 458b03594baf
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/sha1.c	Sun Oct 21 21:57:22 2007 -0400
     1.3 @@ -0,0 +1,151 @@
     1.4 +/*
     1.5 + * The contents of this file are subject to the Mozilla Public
     1.6 + * License Version 1.1 (the "License"); you may not use this file
     1.7 + * except in compliance with the License. You may obtain a copy of
     1.8 + * the License at http://www.mozilla.org/MPL/
     1.9 + *
    1.10 + * Software distributed under the License is distributed on an "AS
    1.11 + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
    1.12 + * implied. See the License for the specific language governing
    1.13 + * rights and limitations under the License.
    1.14 + *
    1.15 + * The Original Code is SHA 180-1 Reference Implementation (Compact version)
    1.16 + *
    1.17 + * The Initial Developer of the Original Code is Paul Kocher of
    1.18 + * Cryptography Research.  Portions created by Paul Kocher are
    1.19 + * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
    1.20 + * Rights Reserved.
    1.21 + *
    1.22 + * Contributor(s):
    1.23 + *
    1.24 + *     Paul Kocher
    1.25 + *
    1.26 + * Alternatively, the contents of this file may be used under the
    1.27 + * terms of the GNU General Public License Version 2 or later (the
    1.28 + * "GPL"), in which case the provisions of the GPL are applicable
    1.29 + * instead of those above.  If you wish to allow use of your
    1.30 + * version of this file only under the terms of the GPL and not to
    1.31 + * allow others to use your version of this file under the MPL,
    1.32 + * indicate your decision by deleting the provisions above and
    1.33 + * replace them with the notice and other provisions required by
    1.34 + * the GPL.  If you do not delete the provisions above, a recipient
    1.35 + * may use your version of this file under either the MPL or the
    1.36 + * GPL.
    1.37 + */
    1.38 +
    1.39 +#include "sha1.h"
    1.40 +
    1.41 +static void shaHashBlock(SHA_CTX *ctx);
    1.42 +
    1.43 +void SHA1_Init(SHA_CTX *ctx) {
    1.44 +  int i;
    1.45 +
    1.46 +  ctx->lenW = 0;
    1.47 +  ctx->sizeHi = ctx->sizeLo = 0;
    1.48 +
    1.49 +  /* Initialize H with the magic constants (see FIPS180 for constants)
    1.50 +   */
    1.51 +  ctx->H[0] = 0x67452301;
    1.52 +  ctx->H[1] = 0xefcdab89;
    1.53 +  ctx->H[2] = 0x98badcfe;
    1.54 +  ctx->H[3] = 0x10325476;
    1.55 +  ctx->H[4] = 0xc3d2e1f0;
    1.56 +
    1.57 +  for (i = 0; i < 80; i++)
    1.58 +    ctx->W[i] = 0;
    1.59 +}
    1.60 +
    1.61 +
    1.62 +void SHA1_Update(SHA_CTX *ctx, const void *_dataIn, int len) {
    1.63 +  const unsigned char *dataIn = _dataIn;
    1.64 +  int i;
    1.65 +
    1.66 +  /* Read the data into W and process blocks as they get full
    1.67 +   */
    1.68 +  for (i = 0; i < len; i++) {
    1.69 +    ctx->W[ctx->lenW / 4] <<= 8;
    1.70 +    ctx->W[ctx->lenW / 4] |= (unsigned int)dataIn[i];
    1.71 +    if ((++ctx->lenW) % 64 == 0) {
    1.72 +      shaHashBlock(ctx);
    1.73 +      ctx->lenW = 0;
    1.74 +    }
    1.75 +    ctx->sizeLo += 8;
    1.76 +    ctx->sizeHi += (ctx->sizeLo < 8);
    1.77 +  }
    1.78 +}
    1.79 +
    1.80 +
    1.81 +void SHA1_Final(unsigned char hashout[20], SHA_CTX *ctx) {
    1.82 +  unsigned char pad0x80 = 0x80;
    1.83 +  unsigned char pad0x00 = 0x00;
    1.84 +  unsigned char padlen[8];
    1.85 +  int i;
    1.86 +
    1.87 +  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
    1.88 +   */
    1.89 +  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
    1.90 +  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
    1.91 +  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
    1.92 +  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
    1.93 +  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
    1.94 +  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
    1.95 +  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
    1.96 +  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
    1.97 +  SHA1_Update(ctx, &pad0x80, 1);
    1.98 +  while (ctx->lenW != 56)
    1.99 +    SHA1_Update(ctx, &pad0x00, 1);
   1.100 +  SHA1_Update(ctx, padlen, 8);
   1.101 +
   1.102 +  /* Output hash
   1.103 +   */
   1.104 +  for (i = 0; i < 20; i++) {
   1.105 +    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
   1.106 +    ctx->H[i / 4] <<= 8;
   1.107 +  }
   1.108 +
   1.109 +  /*
   1.110 +   *  Re-initialize the context (also zeroizes contents)
   1.111 +   */
   1.112 +  SHA1_Init(ctx);
   1.113 +}
   1.114 +
   1.115 +
   1.116 +#define SHA_ROT(X,n) (((X) << (n)) | ((X) >> (32-(n))))
   1.117 +
   1.118 +static void shaHashBlock(SHA_CTX *ctx) {
   1.119 +  int t;
   1.120 +  unsigned int A,B,C,D,E,TEMP;
   1.121 +
   1.122 +  for (t = 16; t <= 79; t++)
   1.123 +    ctx->W[t] =
   1.124 +      SHA_ROT(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
   1.125 +
   1.126 +  A = ctx->H[0];
   1.127 +  B = ctx->H[1];
   1.128 +  C = ctx->H[2];
   1.129 +  D = ctx->H[3];
   1.130 +  E = ctx->H[4];
   1.131 +
   1.132 +  for (t = 0; t <= 19; t++) {
   1.133 +    TEMP = SHA_ROT(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999;
   1.134 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   1.135 +  }
   1.136 +  for (t = 20; t <= 39; t++) {
   1.137 +    TEMP = SHA_ROT(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1;
   1.138 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   1.139 +  }
   1.140 +  for (t = 40; t <= 59; t++) {
   1.141 +    TEMP = SHA_ROT(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdc;
   1.142 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   1.143 +  }
   1.144 +  for (t = 60; t <= 79; t++) {
   1.145 +    TEMP = SHA_ROT(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6;
   1.146 +    E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
   1.147 +  }
   1.148 +
   1.149 +  ctx->H[0] += A;
   1.150 +  ctx->H[1] += B;
   1.151 +  ctx->H[2] += C;
   1.152 +  ctx->H[3] += D;
   1.153 +  ctx->H[4] += E;
   1.154 +}