diff --git a/sha1.asm b/sha1.asm index 88769ba..8f2dcf6 100644 --- a/sha1.asm +++ b/sha1.asm @@ -2,14 +2,14 @@ mcopy sha1.macros * Direct page locations -;chunk gequ 0 -a_ gequ 8 ; elements of state -b gequ 12 -c gequ 16 -d gequ 20 -e gequ 24 -idx gequ 28 -unused gequ 30 +length gequ 0 +extra gequ 8 +idx gequ 10 +a_ gequ 12 ; elements of state +b gequ 16 +c gequ 20 +d gequ 24 +e gequ 28 f_plus_k gequ 32 temp gequ 36 h0 gequ 40 @@ -49,6 +49,12 @@ SHA1_INIT start sta h4 lda #$C3D2 sta h4+2 + + stz length + stz length+2 + stz length+4 + stz length+6 + stz extra rtl end diff --git a/sha1.cc b/sha1.cc new file mode 100644 index 0000000..7bdb77a --- /dev/null +++ b/sha1.cc @@ -0,0 +1,139 @@ +#pragma noroot +#pragma lint -1 +#pragma optimize -1 + +#include "sha1.h" +#include + +#define length_offset 0 +#define extra_offset 8 +#define hash_offset 40 +#define data_offset 60 + +extern void SHA1_PROCESSCHUNK(void); + +void sha1_update(struct sha1_context *context, + const unsigned char *data, + unsigned long length) +{ + unsigned int extra = context->extra; + + context->length += length; + + if (extra > 0) { + if (length >= 64 - extra) { + memcpy(&context->chunk[extra], data, 64 - extra); + sha1_processchunk(context); + length -= 64 - extra; + data += 64 - extra; + } else { + memcpy(&context->chunk[extra], data, length); + context->extra += length; + return; + } + } + + while (length >= 64) { + memcpy(&context->chunk, data, 64); + sha1_processchunk(context); + length -= 64; + data += 64; + } + + memcpy(&context->chunk, data, length); + context->extra = length; +} + + +void sha1_finalize(struct sha1_context *context) +{ + unsigned int extra = context->extra; + + context->chunk[extra++] = 0x80; + + memset(&context->chunk[extra], 0, 64 - extra); + + if (extra > 64 - 8) { + sha1_processchunk(context); + memset(&context->chunk, 0, 64); + } + + /* Append total length in bits */ + asm { + phd + lda context + tcd + + asl length_offset + rol length_offset+2 + rol length_offset+4 + rol length_offset+6 + asl length_offset + rol length_offset+2 + rol length_offset+4 + rol length_offset+6 + asl length_offset + rol length_offset+2 + rol length_offset+4 + rol length_offset+6 + + lda length_offset+6 + xba + sta data_offset+56 + lda length_offset+4 + xba + sta data_offset+58 + lda length_offset+2 + xba + sta data_offset+60 + lda length_offset + xba + sta data_offset+62 + + jsl SHA1_PROCESSCHUNK + + lda hash_offset + xba + tay + lda hash_offset+2 + xba + sta hash_offset + sty hash_offset+2 + + lda hash_offset+4 + xba + tay + lda hash_offset+4+2 + xba + sta hash_offset+4 + sty hash_offset+4+2 + + lda hash_offset+8 + xba + tay + lda hash_offset+8+2 + xba + sta hash_offset+8 + sty hash_offset+8+2 + + lda hash_offset+12 + xba + tay + lda hash_offset+12+2 + xba + sta hash_offset+12 + sty hash_offset+12+2 + + lda hash_offset+16 + xba + tay + lda hash_offset+16+2 + xba + sta hash_offset+16 + sty hash_offset+16+2 + + pld + } +} + +#append "sha1.asm" diff --git a/sha1.h b/sha1.h index dcf0481..39ebb12 100644 --- a/sha1.h +++ b/sha1.h @@ -1,11 +1,16 @@ struct sha1_context { - unsigned char reserved1[8]; - unsigned long a,b,c,d,e; - unsigned char reserved2[12]; - unsigned long h0,h1,h2,h3,h4; + unsigned long length; + unsigned long length2; + unsigned short extra; + unsigned char reserved1[30]; + unsigned char hash[20]; unsigned char chunk[64]; - unsigned char reserved3[300]; + unsigned char reserved2[16]; }; -int sha1_init(struct sha1_context *context); -int sha1_processchunk(struct sha1_context *context); +void sha1_init(struct sha1_context *context); +void sha1_processchunk(struct sha1_context *context); + +void sha1_update(struct sha1_context *context, const unsigned char *data, unsigned long length); + +void sha1_finalize(struct sha1_context *context); diff --git a/sha1test.c b/sha1test.c index 20dc787..0298ae6 100644 --- a/sha1test.c +++ b/sha1test.c @@ -3,14 +3,15 @@ #include #include #include +#include -int main(void) { +int main(int argc, char **argv) { unsigned int i; unsigned long tick_count; long double bytes_per_sec; struct sha1_context *context, **context_hndl; - struct sha1_context context_init = {{0}, 0,0,0,0,0, {0}, 0,0,0,0,0, + struct sha1_context context_init = {0,0,0, {0}, {0}, {0x61,0x62,0x63,0x80, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, @@ -40,8 +41,12 @@ int main(void) { sha1_init(context); sha1_processchunk(context); - printf("abcde = %08lx %08lx %08lx %08lx %08lx\n", context->a, context->b, context->c, context->d, context->e); - printf("h[..] = %08lx %08lx %08lx %08lx %08lx\n", context->h0, context->h1, context->h2, context->h3, context->h4); + printf("h[..] = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", + context->hash[3], context->hash[2], context->hash[1], context->hash[0], + context->hash[7], context->hash[6], context->hash[5], context->hash[4], + context->hash[11], context->hash[10], context->hash[9], context->hash[8], + context->hash[15], context->hash[14], context->hash[13], context->hash[12], + context->hash[19], context->hash[18], context->hash[17], context->hash[16]); tick_count = GetTick(); for (i = 0; i < 1000; i++) { @@ -51,4 +56,25 @@ int main(void) { bytes_per_sec = (long double)1000 * 64 * 60 / tick_count; printf("Time for 1000 iters = %lu ticks (%lf bytes/sec)\n", tick_count, bytes_per_sec); + + tick_count = GetTick(); + sha1_init(context); + sha1_update(context, (void*)0x030000, 64000); + sha1_finalize(context); + tick_count = GetTick() - tick_count; + bytes_per_sec = (long double)1000 * 64 * 60 / tick_count; + printf("Append time = %lu ticks (%lf bytes/sec)\n", tick_count, bytes_per_sec); + + if (argc > 1) { + sha1_init(context); + sha1_update(context, argv[1], strlen(argv[1])); + sha1_finalize(context); + + printf("h[..] = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n", + context->hash[0], context->hash[1], context->hash[2], context->hash[3], + context->hash[4], context->hash[5], context->hash[6], context->hash[7], + context->hash[8], context->hash[9], context->hash[10], context->hash[11], + context->hash[12], context->hash[13], context->hash[14], context->hash[15], + context->hash[16], context->hash[17], context->hash[18], context->hash[19]); + } }