00001
00022 #include "sha256.hpp"
00023 #include <stdio.h>
00024 #include <signal.h>
00025 #include <cstring>
00026 #include <string>
00027 #include <sstream>
00028 #include <iomanip>
00029 #include <iostream>
00030
00031 using namespace std;
00032
00033 void crypt_argchk(char *v, char *s, int d)
00034 {
00035 fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
00036 v, d, s);
00037 exit(1);
00038 }
00039
00040 const struct ltc_hash_descriptor sha256_desc =
00041 {
00042 "sha256",
00043 0,
00044 32,
00045 64,
00046
00047
00048 { 2, 16, 840, 1, 101, 3, 4, 2, 1, },
00049 9,
00050
00051 &sha256_init,
00052 &sha256_process,
00053 &sha256_done,
00054 NULL,
00055 NULL
00056 };
00057
00058
00059
00060 static const ulong32 K[64] =
00061 {
00062 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
00063 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
00064 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
00065 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
00066 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
00067 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
00068 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
00069 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
00070 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
00071 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
00072 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
00073 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
00074 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
00075 };
00076
00077
00078 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
00079 #define Maj(x,y,z) (((x | y) & z) | (x & y))
00080 #define S(x, n) RORc((x),(n))
00081 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
00082 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
00083 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
00084 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
00085 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
00086
00087
00088 #ifdef LTC_CLEAN_STACK
00089 static int _sha256_compress(hash_state * md, unsigned char *buf)
00090 #else
00091 static int sha256_compress(hash_state * md, unsigned char *buf)
00092 #endif
00093 {
00094 ulong32 S[8], W[64], t0, t1;
00095 #ifdef LTC_SMALL_CODE
00096
00097 ulong32 t;
00098 #endif
00099
00100 int i;
00101
00102
00103 for (i = 0; i < 8; i++)
00104 {
00105 S[i] = md->sha256.state[i];
00106 }
00107
00108
00109 for (i = 0; i < 16; i++)
00110 {
00111 LOAD32H(W[i], buf + (4*i));
00112 }
00113
00114
00115 for (i = 16; i < 64; i++)
00116 {
00117 W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
00118 }
00119
00120
00121 #ifdef LTC_SMALL_CODE
00122 #define RND(a,b,c,d,e,f,g,h,i) \
00123 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
00124 t1 = Sigma0(a) + Maj(a, b, c); \
00125 d += t0; \
00126 h = t0 + t1;
00127
00128 for (i = 0; i < 64; ++i)
00129 {
00130 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
00131 t = S[7];
00132 S[7] = S[6];
00133 S[6] = S[5];
00134 S[5] = S[4];
00135 S[4] = S[3];
00136 S[3] = S[2];
00137 S[2] = S[1];
00138 S[1] = S[0];
00139 S[0] = t;
00140 }
00141 #else
00142 #define RND(a,b,c,d,e,f,g,h,i,ki) \
00143 t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
00144 t1 = Sigma0(a) + Maj(a, b, c); \
00145 d += t0; \
00146 h = t0 + t1;
00147
00148 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
00149 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
00150 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
00151 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
00152 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
00153 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
00154 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
00155 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
00156 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
00157 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
00158 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
00159 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
00160 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
00161 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
00162 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
00163 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
00164 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
00165 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
00166 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
00167 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
00168 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
00169 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
00170 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
00171 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
00172 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
00173 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
00174 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
00175 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
00176 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
00177 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
00178 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
00179 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
00180 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
00181 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
00182 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
00183 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
00184 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
00185 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
00186 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
00187 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
00188 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
00189 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
00190 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
00191 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
00192 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
00193 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
00194 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
00195 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
00196 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
00197 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
00198 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
00199 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
00200 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
00201 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
00202 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
00203 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
00204 RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
00205 RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
00206 RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
00207 RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
00208 RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
00209 RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
00210 RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
00211 RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
00212
00213 #undef RND
00214
00215 #endif
00216
00217
00218 for (i = 0; i < 8; i++)
00219 {
00220 md->sha256.state[i] = md->sha256.state[i] + S[i];
00221 }
00222 return CRYPT_OK;
00223 }
00224
00225 #ifdef LTC_CLEAN_STACK
00226 static int sha256_compress(hash_state * md, unsigned char *buf)
00227 {
00228 int err;
00229 err = _sha256_compress(md, buf);
00230 burn_stack(sizeof(ulong32) * 74);
00231 return err;
00232 }
00233 #endif
00234
00235 int sha256_init(hash_state * md)
00236 {
00237 LTC_ARGCHK(md != NULL);
00238
00239 md->sha256.curlen = 0;
00240 md->sha256.length = 0;
00241 md->sha256.state[0] = 0x6A09E667UL;
00242 md->sha256.state[1] = 0xBB67AE85UL;
00243 md->sha256.state[2] = 0x3C6EF372UL;
00244 md->sha256.state[3] = 0xA54FF53AUL;
00245 md->sha256.state[4] = 0x510E527FUL;
00246 md->sha256.state[5] = 0x9B05688CUL;
00247 md->sha256.state[6] = 0x1F83D9ABUL;
00248 md->sha256.state[7] = 0x5BE0CD19UL;
00249 return CRYPT_OK;
00250 }
00251
00252 HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
00253
00254 int sha256_done(hash_state * md, unsigned char *out)
00255 {
00256 int i;
00257
00258 LTC_ARGCHK(md != NULL);
00259 LTC_ARGCHK(out != NULL);
00260
00261 if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
00262 return CRYPT_INVALID_ARG;
00263 }
00264
00265
00266
00267 md->sha256.length += md->sha256.curlen * 8;
00268
00269
00270 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
00271
00272
00273
00274
00275
00276 if (md->sha256.curlen > 56) {
00277 while (md->sha256.curlen < 64) {
00278 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
00279 }
00280 sha256_compress(md, md->sha256.buf);
00281 md->sha256.curlen = 0;
00282 }
00283
00284
00285 while (md->sha256.curlen < 56) {
00286 md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
00287 }
00288
00289
00290 STORE64H(md->sha256.length, md->sha256.buf+56);
00291 sha256_compress(md, md->sha256.buf);
00292
00293
00294 for (i = 0; i < 8; i++) {
00295 STORE32H(md->sha256.state[i], out+(4*i));
00296 }
00297 #ifdef LTC_CLEAN_STACK
00298 zeromem(md, sizeof(hash_state));
00299 #endif
00300
00301 return CRYPT_OK;
00302 }
00303
00304
00305 string hexaDeHash(unsigned char *hash, int l)
00306 {
00307 int i;
00308 stringstream ss;
00309 ss.str("");
00310 ss.clear();
00311 for (i=0; i< l; i++) {
00312 ss << setfill('0') << setw(2) << setbase(16) <<
00313 (unsigned int)hash[i];
00314 }
00315 return ss.str();
00316 }
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 std::string sha256archivo(std::string narch)
00330 {
00331 FILE *file;
00332 hash_state md;
00333 int len;
00334 unsigned char colchon[1024], hash[33];
00335
00336 if ((file = fopen (narch.c_str(), "rb")) == NULL) {
00337 cerr << "sha256archivo no pudo abrir archivo '" <<
00338 narch << "'" << endl;
00339 exit(1);
00340 }
00341
00342 sha256_init(&md);
00343
00344 while ( (len = fread (colchon, 1, 1024, file)) ) {
00345 sha256_process(&md, colchon, len);
00346 }
00347
00348 sha256_done(&md, hash);
00349 fclose (file);
00350
00351 return hexaDeHash(hash, 32);
00352 }
00353
00354
00355
00356
00357
00358 #ifdef EJEMPLO_SHA256
00359
00360 int main()
00361 {
00362 hash_state md;
00363 unsigned char *in = (unsigned char *)"hola mundo", out[33];
00364 sha256_init(&md);
00365 sha256_process(&md, (const unsigned char *)in, strlen((char *)in));
00366 sha256_done(&md, out);
00367 int i;
00368 for (i=0; i< 32; i++) {
00369 printf("%02x", out[i]);
00370 }
00371 printf("\n");
00372 return 0;
00373 }
00374
00375 #endif