~ubuntu-branches/ubuntu/trusty/rhash/trusty

« back to all changes in this revision

Viewing changes to librhash/sha256.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexey S Kravchenko
  • Date: 2011-06-15 01:03:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110615010334-ochayini7ut2djvs
Tags: 1.2.6-1
* New upstream release version 1.2.6
 - ABI changed - now librhash0.0 is librhash0
 - OpenSSL support for faster hash calculation if libssl is installed
   (fully optional) for both rhash and librhash0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* sha256.c - an implementation of SHA-256/224 hash functions
2
2
 * based on FIPS 180-3 (Federal Information Processing Standart).
3
3
 *
4
 
 * Implementation written by Alexei Kravchenko.
 
4
 * Copyright: 2010 Alexey Kravchenko <rhash.admin@gmail.com>
5
5
 *
6
 
 * Copyleft:
7
 
 * I hereby release this code into the public domain. This applies worldwide.
8
 
 * I grant any entity the right to use this work for ANY PURPOSE,
9
 
 * without any conditions, unless such conditions are required by law.
 
6
 * Permission is hereby granted,  free of charge,  to any person  obtaining a
 
7
 * copy of this software and associated documentation files (the "Software"),
 
8
 * to deal in the Software without restriction,  including without limitation
 
9
 * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
 
10
 * and/or sell copies  of  the Software,  and to permit  persons  to whom the
 
11
 * Software is furnished to do so.
10
12
 */
11
13
 
12
14
#include <string.h>
16
18
/* SHA-224 and SHA-256 constants for 64 rounds. These words represent
17
19
 * the first 32 bits of the fractional parts of the cube
18
20
 * roots of the first 64 prime numbers. */
19
 
static const unsigned K256[64] = {
20
 
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
21
 
  0x923f82a4, 0xab1c5ed5,  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
22
 
  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 
23
 
  0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
24
 
  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
25
 
  0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
26
 
  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
27
 
  0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
28
 
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
29
 
  0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
30
 
  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 
21
static const unsigned rhash_k256[64] = {
 
22
        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
 
23
        0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
 
24
        0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 
 
25
        0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
 
26
        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
 
27
        0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
 
28
        0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
 
29
        0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
 
30
        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
 
31
        0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
 
32
        0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
31
33
};
32
34
 
33
35
/* The SHA256/224 functions defined by FIPS 180-3, 4.1.2 */
44
46
/* Recalculate element n-th of circular buffer W using formula
45
47
 *   W[n] = sigma1(W[n-2]) + W[n-7] + sigma0(W[n-15]) + W[n-16]; */
46
48
#define RECALCULATE_W(W,n) \
47
 
  (W[n] += (sigma1(W[(n-2) & 15]) + W[(n-7) & 15] + sigma0(W[(n-15) & 15])))
 
49
        (W[n] += (sigma1(W[(n-2) & 15]) + W[(n-7) & 15] + sigma0(W[(n-15) & 15])))
48
50
 
49
51
#define ROUND(a,b,c,d,e,f,g,h,k,data) { \
50
 
  unsigned T1 = h + Sigma1(e) + Ch(e,f,g) + k + (data); \
51
 
  d += T1, h = T1 + Sigma0(a) + Maj(a,b,c); }
 
52
        unsigned T1 = h + Sigma1(e) + Ch(e,f,g) + k + (data); \
 
53
        d += T1, h = T1 + Sigma0(a) + Maj(a,b,c); }
52
54
#define ROUND_1_16(a,b,c,d,e,f,g,h,n) \
53
 
  ROUND(a,b,c,d,e,f,g,h, K256[n], W[n] = be2me_32(block[n]))
 
55
        ROUND(a,b,c,d,e,f,g,h, rhash_k256[n], W[n] = be2me_32(block[n]))
54
56
#define ROUND_17_64(a,b,c,d,e,f,g,h,n) \
55
 
  ROUND(a,b,c,d,e,f,g,h, k[n], RECALCULATE_W(W, n))
 
57
        ROUND(a,b,c,d,e,f,g,h, k[n], RECALCULATE_W(W, n))
56
58
 
57
59
/**
58
60
 * Initialize context before calculaing hash.
59
61
 *
60
62
 * @param ctx context to initalize
61
63
 */
62
 
void sha256_init(sha256_ctx *ctx)
 
64
void rhash_sha256_init(sha256_ctx *ctx)
63
65
{
64
 
  /* Initial values. These words were obtained by taking the first 32
65
 
   * bits of the fractional parts of the square roots of the first
66
 
   * eight prime numbers. */
67
 
  static const unsigned SHA256_H0[8] = {
68
 
    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
69
 
    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
70
 
  };
71
 
  
72
 
  ctx->length = 0;
73
 
  ctx->digest_length = sha256_hash_size;
74
 
 
75
 
  /* initialize algorithm state */
76
 
  memcpy(ctx->hash, SHA256_H0, sizeof(ctx->hash));
 
66
        /* Initial values. These words were obtained by taking the first 32
 
67
         * bits of the fractional parts of the square roots of the first
 
68
         * eight prime numbers. */
 
69
        static const unsigned SHA256_H0[8] = {
 
70
                0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
 
71
                0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
 
72
        };
 
73
 
 
74
        ctx->length = 0;
 
75
        ctx->digest_length = sha256_hash_size;
 
76
 
 
77
        /* initialize algorithm state */
 
78
        memcpy(ctx->hash, SHA256_H0, sizeof(ctx->hash));
77
79
}
78
80
 
79
81
/**
81
83
 *
82
84
 * @param ctx context to initalize
83
85
 */
84
 
void sha224_init(struct sha256_ctx *ctx)
 
86
void rhash_sha224_init(struct sha256_ctx *ctx)
85
87
{
86
 
  /* Initial values from FIPS 180-3. These words were obtained by taking
87
 
   * bits from 33th to 64th of the fractional parts of the square
88
 
   * roots of ninth through sixteenth prime numbers. */
89
 
  static const unsigned SHA224_H0[8] = {
90
 
    0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 
91
 
    0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
92
 
  };
93
 
 
94
 
  ctx->length = 0;
95
 
  ctx->digest_length = sha224_hash_size;
96
 
 
97
 
  memcpy(ctx->hash, SHA224_H0, sizeof(ctx->hash));
 
88
        /* Initial values from FIPS 180-3. These words were obtained by taking
 
89
         * bits from 33th to 64th of the fractional parts of the square
 
90
         * roots of ninth through sixteenth prime numbers. */
 
91
        static const unsigned SHA224_H0[8] = {
 
92
                0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 
 
93
                0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
 
94
        };
 
95
 
 
96
        ctx->length = 0;
 
97
        ctx->digest_length = sha224_hash_size;
 
98
 
 
99
        memcpy(ctx->hash, SHA224_H0, sizeof(ctx->hash));
98
100
}
99
101
 
100
102
/**
103
105
 * @param hash algorithm state
104
106
 * @param block the message block to process
105
107
 */
106
 
static void sha256_process_block(unsigned hash[8], unsigned block[16])
 
108
static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16])
107
109
{
108
 
  unsigned A, B, C, D, E, F, G, H;
109
 
  unsigned W[16];
110
 
  const unsigned *k;
111
 
  int i;
112
 
 
113
 
  A = hash[0], B = hash[1], C = hash[2], D = hash[3];
114
 
  E = hash[4], F = hash[5], G = hash[6], H = hash[7];
115
 
 
116
 
  /* Compute SHA using alternate Method: FIPS 180-3 6.1.3 */
117
 
  ROUND_1_16(A, B, C, D, E, F, G, H, 0);
118
 
  ROUND_1_16(H, A, B, C, D, E, F, G, 1);
119
 
  ROUND_1_16(G, H, A, B, C, D, E, F, 2);
120
 
  ROUND_1_16(F, G, H, A, B, C, D, E, 3);
121
 
  ROUND_1_16(E, F, G, H, A, B, C, D, 4);
122
 
  ROUND_1_16(D, E, F, G, H, A, B, C, 5);
123
 
  ROUND_1_16(C, D, E, F, G, H, A, B, 6);
124
 
  ROUND_1_16(B, C, D, E, F, G, H, A, 7);
125
 
  ROUND_1_16(A, B, C, D, E, F, G, H, 8);
126
 
  ROUND_1_16(H, A, B, C, D, E, F, G, 9);
127
 
  ROUND_1_16(G, H, A, B, C, D, E, F, 10);
128
 
  ROUND_1_16(F, G, H, A, B, C, D, E, 11);
129
 
  ROUND_1_16(E, F, G, H, A, B, C, D, 12);
130
 
  ROUND_1_16(D, E, F, G, H, A, B, C, 13);
131
 
  ROUND_1_16(C, D, E, F, G, H, A, B, 14);
132
 
  ROUND_1_16(B, C, D, E, F, G, H, A, 15);
133
 
 
134
 
  for(i = 16, k = &K256[16]; i < 64; i += 16, k += 16) {
135
 
    ROUND_17_64(A, B, C, D, E, F, G, H,  0);
136
 
    ROUND_17_64(H, A, B, C, D, E, F, G,  1);
137
 
    ROUND_17_64(G, H, A, B, C, D, E, F,  2);
138
 
    ROUND_17_64(F, G, H, A, B, C, D, E,  3);
139
 
    ROUND_17_64(E, F, G, H, A, B, C, D,  4);
140
 
    ROUND_17_64(D, E, F, G, H, A, B, C,  5);
141
 
    ROUND_17_64(C, D, E, F, G, H, A, B,  6);
142
 
    ROUND_17_64(B, C, D, E, F, G, H, A,  7);
143
 
    ROUND_17_64(A, B, C, D, E, F, G, H,  8);
144
 
    ROUND_17_64(H, A, B, C, D, E, F, G,  9);
145
 
    ROUND_17_64(G, H, A, B, C, D, E, F, 10);
146
 
    ROUND_17_64(F, G, H, A, B, C, D, E, 11);
147
 
    ROUND_17_64(E, F, G, H, A, B, C, D, 12);
148
 
    ROUND_17_64(D, E, F, G, H, A, B, C, 13);
149
 
    ROUND_17_64(C, D, E, F, G, H, A, B, 14);
150
 
    ROUND_17_64(B, C, D, E, F, G, H, A, 15);
151
 
  }
152
 
 
153
 
  hash[0] += A, hash[1] += B, hash[2] += C, hash[3] += D;
154
 
  hash[4] += E, hash[5] += F, hash[6] += G, hash[7] += H;
 
110
        unsigned A, B, C, D, E, F, G, H;
 
111
        unsigned W[16];
 
112
        const unsigned *k;
 
113
        int i;
 
114
 
 
115
        A = hash[0], B = hash[1], C = hash[2], D = hash[3];
 
116
        E = hash[4], F = hash[5], G = hash[6], H = hash[7];
 
117
 
 
118
        /* Compute SHA using alternate Method: FIPS 180-3 6.1.3 */
 
119
        ROUND_1_16(A, B, C, D, E, F, G, H, 0);
 
120
        ROUND_1_16(H, A, B, C, D, E, F, G, 1);
 
121
        ROUND_1_16(G, H, A, B, C, D, E, F, 2);
 
122
        ROUND_1_16(F, G, H, A, B, C, D, E, 3);
 
123
        ROUND_1_16(E, F, G, H, A, B, C, D, 4);
 
124
        ROUND_1_16(D, E, F, G, H, A, B, C, 5);
 
125
        ROUND_1_16(C, D, E, F, G, H, A, B, 6);
 
126
        ROUND_1_16(B, C, D, E, F, G, H, A, 7);
 
127
        ROUND_1_16(A, B, C, D, E, F, G, H, 8);
 
128
        ROUND_1_16(H, A, B, C, D, E, F, G, 9);
 
129
        ROUND_1_16(G, H, A, B, C, D, E, F, 10);
 
130
        ROUND_1_16(F, G, H, A, B, C, D, E, 11);
 
131
        ROUND_1_16(E, F, G, H, A, B, C, D, 12);
 
132
        ROUND_1_16(D, E, F, G, H, A, B, C, 13);
 
133
        ROUND_1_16(C, D, E, F, G, H, A, B, 14);
 
134
        ROUND_1_16(B, C, D, E, F, G, H, A, 15);
 
135
 
 
136
        for(i = 16, k = &rhash_k256[16]; i < 64; i += 16, k += 16) {
 
137
                ROUND_17_64(A, B, C, D, E, F, G, H,  0);
 
138
                ROUND_17_64(H, A, B, C, D, E, F, G,  1);
 
139
                ROUND_17_64(G, H, A, B, C, D, E, F,  2);
 
140
                ROUND_17_64(F, G, H, A, B, C, D, E,  3);
 
141
                ROUND_17_64(E, F, G, H, A, B, C, D,  4);
 
142
                ROUND_17_64(D, E, F, G, H, A, B, C,  5);
 
143
                ROUND_17_64(C, D, E, F, G, H, A, B,  6);
 
144
                ROUND_17_64(B, C, D, E, F, G, H, A,  7);
 
145
                ROUND_17_64(A, B, C, D, E, F, G, H,  8);
 
146
                ROUND_17_64(H, A, B, C, D, E, F, G,  9);
 
147
                ROUND_17_64(G, H, A, B, C, D, E, F, 10);
 
148
                ROUND_17_64(F, G, H, A, B, C, D, E, 11);
 
149
                ROUND_17_64(E, F, G, H, A, B, C, D, 12);
 
150
                ROUND_17_64(D, E, F, G, H, A, B, C, 13);
 
151
                ROUND_17_64(C, D, E, F, G, H, A, B, 14);
 
152
                ROUND_17_64(B, C, D, E, F, G, H, A, 15);
 
153
        }
 
154
 
 
155
        hash[0] += A, hash[1] += B, hash[2] += C, hash[3] += D;
 
156
        hash[4] += E, hash[5] += F, hash[6] += G, hash[7] += H;
155
157
}
156
158
 
157
159
/**
162
164
 * @param msg message chunk
163
165
 * @param size length of the message chunk
164
166
 */
165
 
void sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size)
 
167
void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size)
166
168
{
167
 
  size_t index = (size_t)ctx->length & 63;
168
 
  ctx->length += size;
169
 
 
170
 
  /* fill partial block */
171
 
  if(index) {
172
 
    size_t left = sha256_block_size - index;
173
 
    memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
174
 
    if(size < left) return;
175
 
 
176
 
    /* process partial block */
177
 
    sha256_process_block(ctx->hash, (unsigned*)ctx->message);
178
 
    msg  += left;
179
 
    size -= left;
180
 
  }
181
 
  while(size >= sha256_block_size) {
182
 
    unsigned* aligned_message_block;
183
 
    if( IS_ALIGNED_32(msg) ) {
184
 
      /* the most common case is processing of an already aligned message 
185
 
      without copying it */
186
 
      aligned_message_block = (unsigned*)msg;
187
 
    } else {
188
 
      memcpy(ctx->message, msg, sha256_block_size);
189
 
      aligned_message_block = (unsigned*)ctx->message;
190
 
    }
191
 
 
192
 
    sha256_process_block(ctx->hash, aligned_message_block);
193
 
    msg  += sha256_block_size;
194
 
    size -= sha256_block_size;
195
 
  }
196
 
  if(size) {
197
 
    memcpy(ctx->message, msg, size); /* save leftovers */
198
 
  }
 
169
        size_t index = (size_t)ctx->length & 63;
 
170
        ctx->length += size;
 
171
 
 
172
        /* fill partial block */
 
173
        if(index) {
 
174
                size_t left = sha256_block_size - index;
 
175
                memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
 
176
                if(size < left) return;
 
177
 
 
178
                /* process partial block */
 
179
                rhash_sha256_process_block(ctx->hash, (unsigned*)ctx->message);
 
180
                msg  += left;
 
181
                size -= left;
 
182
        }
 
183
        while(size >= sha256_block_size) {
 
184
                unsigned* aligned_message_block;
 
185
                if(IS_ALIGNED_32(msg)) {
 
186
                        /* the most common case is processing of an already aligned message 
 
187
                        without copying it */
 
188
                        aligned_message_block = (unsigned*)msg;
 
189
                } else {
 
190
                        memcpy(ctx->message, msg, sha256_block_size);
 
191
                        aligned_message_block = (unsigned*)ctx->message;
 
192
                }
 
193
 
 
194
                rhash_sha256_process_block(ctx->hash, aligned_message_block);
 
195
                msg  += sha256_block_size;
 
196
                size -= sha256_block_size;
 
197
        }
 
198
        if(size) {
 
199
                memcpy(ctx->message, msg, size); /* save leftovers */
 
200
        }
199
201
}
200
202
 
201
203
/**
204
206
 * @param ctx the algorithm context containing current hashing state
205
207
 * @param result calculated hash in binary form
206
208
 */
207
 
void sha256_final(sha256_ctx *ctx, unsigned char* result)
 
209
void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result)
208
210
{
209
 
  size_t index = ((unsigned)ctx->length & 63) >> 2;
210
 
  unsigned shift = ((unsigned)ctx->length & 3) * 8;
211
 
 
212
 
  /* pad message and run for last block */
213
 
 
214
 
  /* append the byte 0x80 to the message */
215
 
  ctx->message[index]   &= le2me_32(~(0xFFFFFFFF << shift));
216
 
  ctx->message[index++] ^= le2me_32(0x80 << shift);
217
 
 
218
 
  /* if no room left in the message to store 64-bit message length */
219
 
  if(index > 14) {
220
 
    /* then fill the rest with zeros and process it */
221
 
    while(index < 16) {
222
 
      ctx->message[index++] = 0;
223
 
    }
224
 
    sha256_process_block(ctx->hash, ctx->message);
225
 
    index = 0;
226
 
  }
227
 
  while(index < 14) {
228
 
    ctx->message[index++] = 0;
229
 
  }
230
 
  ctx->message[14] = be2me_32( (unsigned)(ctx->length >> 29) );
231
 
  ctx->message[15] = be2me_32( (unsigned)(ctx->length << 3) );
232
 
  sha256_process_block(ctx->hash, ctx->message);
233
 
 
234
 
  if(result) be32_copy(result, ctx->hash, ctx->digest_length);
 
211
        size_t index = ((unsigned)ctx->length & 63) >> 2;
 
212
        unsigned shift = ((unsigned)ctx->length & 3) * 8;
 
213
 
 
214
        /* pad message and run for last block */
 
215
 
 
216
        /* append the byte 0x80 to the message */
 
217
        ctx->message[index]   &= le2me_32(~(0xFFFFFFFF << shift));
 
218
        ctx->message[index++] ^= le2me_32(0x80 << shift);
 
219
 
 
220
        /* if no room left in the message to store 64-bit message length */
 
221
        if(index > 14) {
 
222
                /* then fill the rest with zeros and process it */
 
223
                while(index < 16) {
 
224
                        ctx->message[index++] = 0;
 
225
                }
 
226
                rhash_sha256_process_block(ctx->hash, ctx->message);
 
227
                index = 0;
 
228
        }
 
229
        while(index < 14) {
 
230
                ctx->message[index++] = 0;
 
231
        }
 
232
        ctx->message[14] = be2me_32( (unsigned)(ctx->length >> 29) );
 
233
        ctx->message[15] = be2me_32( (unsigned)(ctx->length << 3) );
 
234
        rhash_sha256_process_block(ctx->hash, ctx->message);
 
235
 
 
236
        if(result) be32_copy(result, 0, ctx->hash, ctx->digest_length);
235
237
}