1. Hash algorithm: C to Euphoria
- Posted by Alan Tu <ATU5713 at COMPUSERVE.COM> Dec 23, 1998
- 448 views
- Last edited Dec 24, 1998
There's a secure hash algorithm called SHA-1. I am asking help to port this C monster to Euphoria; I think it would have several applications in current programs, such as authentication and confirming good decrypts of encrypted files. I don't know any C, so I'm asking for help. Maybe some people can port portions of this to Euphoria. Thanks. Alan Nitty-Gritty /* NIST Secure Hash Algorithm */ /* heavily modified by Uwe Hollerbach uh at alumni.caltech edu */ /* from Peter C. Gutmann's implementation as found in */ /* Applied Cryptography by Bruce Schneier */ /* NIST's proposed modification to SHA of 7/11/94 may be */ /* activated by defining USE_MODIFIED_SHA */ begin source: #include <stdlib.h> #include <stdio.h> #include <string.h> #include "sha.h" /* SHA f()-functions */ #define f1(x,y,z) ((x & y) | (~x & z)) #define f2(x,y,z) (x ^ y ^ z) #define f3(x,y,z) ((x & y) | (x & z) | (y & z)) #define f4(x,y,z) (x ^ y ^ z) /* SHA constants */ #define CONST1 0x5a827999L #define CONST2 0x6ed9eba1L #define CONST3 0x8f1bbcdcL #define CONST4 0xca62c1d6L /* 32-bit rotate */ #define ROT32(x,n) ((x << n) | (x >> (32 - n))) #define FUNC(n,i) \ temp = ROT32(A,5) + f##n(B,C,D) + E + W[i] + CONST##n; \ E = D; D = C; C = ROT32(B,30); B = A; A = temp /* do SHA transformation */ static void sha_transform(SHA_INFO *sha_info) { int i; LONG temp, A, B, C, D, E, W[80]; for (i = 0; i < 16; ++i) { W[i] = sha_info->data[i]; } for (i = 16; i < 80; ++i) { W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16]; #ifdef USE_MODIFIED_SHA W[i] = ROT32(W[i], 1); #endif /* USE_MODIFIED_SHA */ } A = sha_info->digest[0]; B = sha_info->digest[1]; C = sha_info->digest[2]; D = sha_info->digest[3]; E = sha_info->digest[4]; #ifdef UNROLL_LOOPS FUNC(1, 0); FUNC(1, 1); FUNC(1, 2); FUNC(1, 3); FUNC(1, 4); FUNC(1, 5); FUNC(1, 6); FUNC(1, 7); FUNC(1, 8); FUNC(1, 9); FUNC(1,10); FUNC(1,11); FUNC(1,12); FUNC(1,13); FUNC(1,14); FUNC(1,15); FUNC(1,16); FUNC(1,17); FUNC(1,18); FUNC(1,19); FUNC(2,20); FUNC(2,21); FUNC(2,22); FUNC(2,23); FUNC(2,24); FUNC(2,25); FUNC(2,26); FUNC(2,27); FUNC(2,28); FUNC(2,29); FUNC(2,30); FUNC(2,31); FUNC(2,32); FUNC(2,33); FUNC(2,34); FUNC(2,35); FUNC(2,36); FUNC(2,37); FUNC(2,38); FUNC(2,39); FUNC(3,40); FUNC(3,41); FUNC(3,42); FUNC(3,43); FUNC(3,44); FUNC(3,45); FUNC(3,46); FUNC(3,47); FUNC(3,48); FUNC(3,49); FUNC(3,50); FUNC(3,51); FUNC(3,52); FUNC(3,53); FUNC(3,54); FUNC(3,55); FUNC(3,56); FUNC(3,57); FUNC(3,58); FUNC(3,59); FUNC(4,60); FUNC(4,61); FUNC(4,62); FUNC(4,63); FUNC(4,64); FUNC(4,65); FUNC(4,66); FUNC(4,67); FUNC(4,68); FUNC(4,69); FUNC(4,70); FUNC(4,71); FUNC(4,72); FUNC(4,73); FUNC(4,74); FUNC(4,75); FUNC(4,76); FUNC(4,77); FUNC(4,78); FUNC(4,79); #else /* !UNROLL_LOOPS */ for (i = 0; i < 20; ++i) { FUNC(1,i); } for (i = 20; i < 40; ++i) { FUNC(2,i); } for (i = 40; i < 60; ++i) { FUNC(3,i); } for (i = 60; i < 80; ++i) { FUNC(4,i); } #endif /* !UNROLL_LOOPS */ sha_info->digest[0] += A; sha_info->digest[1] += B; sha_info->digest[2] += C; sha_info->digest[3] += D; sha_info->digest[4] += E; } #ifdef LITTLE_ENDIAN /* change endianness of data */ static void byte_reverse(LONG *buffer, int count) { int i; BYTE ct[4], *cp; count /= sizeof(LONG); cp = (BYTE *) buffer; for (i = 0; i < count; ++i) { ct[0] = cp[0]; ct[1] = cp[1]; ct[2] = cp[2]; ct[3] = cp[3]; cp[0] = ct[3]; cp[1] = ct[2]; cp[2] = ct[1]; cp[3] = ct[0]; cp += sizeof(LONG); } } #endif /* LITTLE_ENDIAN */ /* initialize the SHA digest */ void sha_init(SHA_INFO *sha_info) { sha_info->digest[0] = 0x67452301L; sha_info->digest[1] = 0xefcdab89L; sha_info->digest[2] = 0x98badcfeL; sha_info->digest[3] = 0x10325476L; sha_info->digest[4] = 0xc3d2e1f0L; sha_info->count_lo = 0L; sha_info->count_hi = 0L; } /* update the SHA digest */ void sha_update(SHA_INFO *sha_info, BYTE *buffer, int count) { if ((sha_info->count_lo + ((LONG) count << 3)) < sha_info->count_lo) { ++sha_info->count_hi; } sha_info->count_lo += (LONG) count << 3; sha_info->count_hi += (LONG) count >> 29; while (count >= SHA_BLOCKSIZE) { memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); #ifdef LITTLE_ENDIAN byte_reverse(sha_info->data, SHA_BLOCKSIZE); #endif /* LITTLE_ENDIAN */ sha_transform(sha_info); buffer += SHA_BLOCKSIZE; count -= SHA_BLOCKSIZE; } memcpy(sha_info->data, buffer, count); } /* finish computing the SHA digest */ void sha_final(SHA_INFO *sha_info) { int count; LONG lo_bit_count, hi_bit_count; lo_bit_count = sha_info->count_lo; hi_bit_count = sha_info->count_hi; count = (int) ((lo_bit_count >> 3) & 0x3f); ((BYTE *) sha_info->data)[count++] = 0x80; if (count > 56) { memset((BYTE *) &sha_info->data + count, 0, 64 - count); #ifdef LITTLE_ENDIAN byte_reverse(sha_info->data, SHA_BLOCKSIZE); #endif /* LITTLE_ENDIAN */ sha_transform(sha_info); memset(&sha_info->data, 0, 56); } else { memset((BYTE *) &sha_info->data + count, 0, 56 - count); } #ifdef LITTLE_ENDIAN byte_reverse(sha_info->data, SHA_BLOCKSIZE); #endif /* LITTLE_ENDIAN */ sha_info->data[14] = hi_bit_count; sha_info->data[15] = lo_bit_count; sha_transform(sha_info); } /* compute the SHA digest of a FILE stream */ #define BLOCK_SIZE 8192 void sha_stream(SHA_INFO *sha_info, FILE *fin) { int i; BYTE data[BLOCK_SIZE]; sha_init(sha_info); while ((i = fread(data, 1, BLOCK_SIZE, fin)) > 0) { sha_update(sha_info, data, i); } sha_final(sha_info); } /* print a SHA digest */ void sha_print(SHA_INFO *sha_info) { printf("%08lx %08lx %08lx %08lx %08lx\n", sha_info->digest[0], sha_info->digest[1], sha_info->digest[2], sha_info->digest[3], sha_info->digest[4]); } end source
2. Re: Hash algorithm: C to Euphoria
- Posted by Adam Weeden <SkaMan325 at AOL.COM> Dec 24, 1998
- 409 views
I'd be willing to help.
3. Re: Hash algorithm: C to Euphoria
- Posted by Alan Tu <ATU5713 at COMPUSERVE.COM> Dec 24, 1998
- 404 views
Adam Weeden wrote: >I'd be willing to help. Sounds great. See if you can make heads or tails of the C code and port it to, like maybe, to an Euphoria function. Thanks. Alan
4. Re: Hash algorithm: C to Euphoria
- Posted by Adam Weeden <SkaMan325 at AOL.COM> Dec 24, 1998
- 414 views
- Last edited Dec 25, 1998
Just send me the C code.
5. Re: Hash algorithm: C to Euphoria
- Posted by Davi Figueiredo <davitf at USA.NET> Dec 27, 1998
- 435 views
- Last edited Dec 28, 1998
Hi Alan and all interested, Attached is an Euphoria include file which calculates the SHA-1 digest of a string. I didn't translate the C code posted, instead I followed the specification I found at http://www.nist.gov/itl/div897/pubs/fip180-1.htm . The reason I didn't try translating the code was that I know nothing about C (and don't want to learn it either). Anyway, it seems to work ok. If you think it's too slow, maybe someone can speed it up (if someone can understand the code). Regards, Davi Figueiredo davitf at usa.net ____________________________________________________________________ Get free e-mail and a permanent address at http://www.amexmail.com/?A=1