Add implementations of the SHA-1 update and finalize operations.

The definition of the context structure is also cleaned up a bit.
This commit is contained in:
Stephen Heumann 2017-06-30 22:53:59 -05:00
parent 3aa0d1b89f
commit 8b17a15ada
4 changed files with 195 additions and 19 deletions

View File

@ -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

139
sha1.cc Normal file
View File

@ -0,0 +1,139 @@
#pragma noroot
#pragma lint -1
#pragma optimize -1
#include "sha1.h"
#include <string.h>
#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"

19
sha1.h
View File

@ -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);

View File

@ -3,14 +3,15 @@
#include <MiscTool.h>
#include <Memory.h>
#include <orca.h>
#include <string.h>
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]);
}
}