~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/algorithm/sha1.cc

  • Committer: Brian Aker
  • Date: 2009-10-15 00:22:33 UTC
  • mto: (1183.1.11 merge)
  • mto: This revision was merged to the branch mainline in revision 1198.
  • Revision ID: brian@gaz-20091015002233-fa4ao2mbc67wls91
First pass of information engine. OMG, ponies... is it so much easier to
deal with creating and engine.

The list table iterator though... its ass, needs to go. We should also
abstract out share. Very few engines need a custom one. Just say'in

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2010 nobody (this is public domain)
3
 
 */
4
 
 
5
 
/**
6
 
 * @file
7
 
 * @brief SHA1 Definitions
8
 
 */
9
 
 
10
 
/*
11
 
 * SHA-1 in C
12
 
 * 
13
 
 * This file is based on public domain code.
14
 
 * Initial source code is in the public domain, 
15
 
 * so clarified by Steve Reid <steve@edmweb.com>
16
 
 *
17
 
 * Test Vectors (from FIPS PUB 180-1)
18
 
 * "abc"
19
 
 *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
20
 
 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
21
 
 *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
22
 
 * A million repetitions of "a"
23
 
 *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
24
 
 */
25
 
 
26
 
#include "config.h"
27
 
#include "sha1.h"
28
 
#include <string.h>
29
 
 
30
 
namespace drizzled
31
 
{
32
 
 
33
 
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
34
 
 
35
 
/* Solaris + gcc don't always define this. */
36
 
#ifndef BYTE_ORDER
37
 
# define LITTLE_ENDIAN 1234
38
 
# define BIG_ENDIAN 4321
39
 
# if defined(sparc) || defined(__sparc) || defined(__sparc__)
40
 
#  define BYTE_ORDER BIG_ENDIAN
41
 
# else
42
 
#  define BYTE_ORDER LITTLE_ENDIAN
43
 
# endif
44
 
#endif /* BYTE_ORDER */
45
 
 
46
 
/*
47
 
 * blk0() and blk() perform the initial expand.
48
 
 * I got the idea of expanding during the round function from SSLeay
49
 
 */
50
 
#if BYTE_ORDER == LITTLE_ENDIAN
51
 
# define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
52
 
    |(rol(block->l[i],8)&0x00FF00FF))
53
 
#else
54
 
# define blk0(i) block->l[i]
55
 
#endif
56
 
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
57
 
    ^block->l[(i+2)&15]^block->l[i&15],1))
58
 
 
59
 
/*
60
 
 * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
61
 
 */
62
 
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
63
 
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
64
 
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
65
 
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
66
 
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
67
 
 
68
 
/*
69
 
 * Hash a single 512-bit block. This is the core of the algorithm.
70
 
 */
71
 
void
72
 
SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH])
73
 
{
74
 
        uint32_t a, b, c, d, e;
75
 
        typedef union {
76
 
                uint8_t c[64];
77
 
                uint32_t l[16];
78
 
        } CHAR64LONG16;
79
 
        CHAR64LONG16 realBlock;
80
 
        CHAR64LONG16 *block= &realBlock;
81
 
 
82
 
        (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
83
 
 
84
 
        /* Copy context->state[] to working vars */
85
 
        a = state[0];
86
 
        b = state[1];
87
 
        c = state[2];
88
 
        d = state[3];
89
 
        e = state[4];
90
 
 
91
 
        /* 4 rounds of 20 operations each. Loop unrolled. */
92
 
        R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
93
 
        R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
94
 
        R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
95
 
        R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
96
 
        R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
97
 
        R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
98
 
        R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
99
 
        R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
100
 
        R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
101
 
        R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
102
 
        R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
103
 
        R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
104
 
        R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
105
 
        R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
106
 
        R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
107
 
        R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
108
 
        R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
109
 
        R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
110
 
        R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
111
 
        R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
112
 
 
113
 
        /* Add the working vars back into context.state[] */
114
 
        state[0] += a;
115
 
        state[1] += b;
116
 
        state[2] += c;
117
 
        state[3] += d;
118
 
        state[4] += e;
119
 
 
120
 
        /* Wipe variables */
121
 
        a = b = c = d = e = 0;
122
 
}
123
 
 
124
 
 
125
 
/*
126
 
 * SHA1Init - Initialize new context
127
 
 */
128
 
void
129
 
SHA1Init(SHA1_CTX *context)
130
 
{
131
 
 
132
 
        /* SHA1 initialization constants */
133
 
        context->count = 0;
134
 
        context->state[0] = 0x67452301;
135
 
        context->state[1] = 0xEFCDAB89;
136
 
        context->state[2] = 0x98BADCFE;
137
 
        context->state[3] = 0x10325476;
138
 
        context->state[4] = 0xC3D2E1F0;
139
 
}
140
 
 
141
 
 
142
 
/*
143
 
 * Run your data through this.
144
 
 */
145
 
void
146
 
SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len)
147
 
{
148
 
        size_t i, j;
149
 
 
150
 
        j = (size_t)((context->count >> 3) & 63);
151
 
        context->count += (len << 3);
152
 
        if ((j + len) > 63) {
153
 
                (void)memcpy(&context->buffer[j], data, (i = 64-j));
154
 
                SHA1Transform(context->state, context->buffer);
155
 
                for ( ; i + 63 < len; i += 64)
156
 
                        SHA1Transform(context->state, (uint8_t *)&data[i]);
157
 
                j = 0;
158
 
        } else {
159
 
                i = 0;
160
 
        }
161
 
        (void)memcpy(&context->buffer[j], &data[i], len - i);
162
 
}
163
 
 
164
 
 
165
 
/*
166
 
 * Add padding and return the message digest.
167
 
 */
168
 
void
169
 
SHA1Pad(SHA1_CTX *context)
170
 
{
171
 
        uint8_t finalcount[8];
172
 
        u_int i;
173
 
 
174
 
        for (i = 0; i < 8; i++) {
175
 
                finalcount[i] = (uint8_t)((context->count >>
176
 
                    ((7 - (i & 7)) * 8)) & 255);        /* Endian independent */
177
 
        }
178
 
        SHA1Update(context, (uint8_t *)"\200", 1);
179
 
        while ((context->count & 504) != 448)
180
 
                SHA1Update(context, (uint8_t *)"\0", 1);
181
 
        SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
182
 
}
183
 
 
184
 
void
185
 
SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
186
 
{
187
 
        u_int i;
188
 
 
189
 
        SHA1Pad(context);
190
 
        if (digest) {
191
 
                for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
192
 
                        digest[i] = (uint8_t)
193
 
                           ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
194
 
                }
195
 
                memset(context, 0, sizeof(*context));
196
 
        }
197
 
}
198
 
 
199
 
} /* namespace drizzled */