Implement MD4.

This is an old and insecure hash algorithm, but some things of interest still use it.
This commit is contained in:
Stephen Heumann 2023-11-30 18:29:50 -06:00
parent c1e1caa766
commit 8469c7744c
9 changed files with 879 additions and 6 deletions

View File

@ -4,7 +4,7 @@ CFLAGS = -O255 -w255
LIBRARIES = lib65816crypto lib65816hash
PROGRAMS = aescbctest aesctrtest aestest aescrypt sha1sum sha1test \
sha256sum sha256test md5sum md5test hmactest
sha256sum sha256test md5sum md5test md4sum md4test hmactest
.PHONY: default
default: $(LIBRARIES) $(PROGRAMS)
@ -33,11 +33,15 @@ md5.a: md5.cc md5.h md5.asm md5.macros hmacimpl.h
$(CC) $(CFLAGS) -c $<
md5.B: md5.a
md4.a: md4.cc md4.h md4.asm md4.macros hmacimpl.h
$(CC) $(CFLAGS) -c $<
md4.B: md4.a
# Libraries
lib65816crypto: aesmodes.a aes.a
rm -f $@
iix makelib -P $@ $(patsubst %,+%,$^)
lib65816hash: sha1.a sha1.B sha256.a sha256.B md5.a md5.B
lib65816hash: sha1.a sha1.B sha256.a sha256.B md5.a md5.B md4.a md4.B
rm -f $@
iix makelib -P $@ $(patsubst %,+%,$^)
@ -66,7 +70,12 @@ md5sum.a: md5sum.c md5.h cksumcommon.h
md5test.a: md5test.c md5.h
$(CC) $(CFLAGS) -c $<
hmactest.a: hmactest.c sha256.h sha1.h md5.h
md4sum.a: md4sum.c md4.h cksumcommon.h
$(CC) $(CFLAGS) -c $<
md4test.a: md4test.c md4.h
$(CC) $(CFLAGS) -c $<
hmactest.a: hmactest.c sha256.h sha1.h md5.h md4.h
$(CC) $(CFLAGS) -c $<
aescbctest: aescbctest.a pagealign.root lib65816crypto
@ -93,6 +102,11 @@ md5sum: md5sum.a pagealign.root lib65816hash
md5test: md5test.a pagealign.root lib65816hash
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816hash -o $@
md4sum: md4sum.a pagealign.root lib65816hash
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816hash -o $@
md4test: md4test.a pagealign.root lib65816hash
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816hash -o $@
hmactest: hmactest.a lib65816hash
$(CC) $(CFLAGS) pagealign.root $< -L. -llib65816hash -o $@

View File

@ -1,7 +1,7 @@
65816 Cryptographic & Hash Libraries
====================================
This package contains libraries implementing cryptographic algorithms for the 65816, suitable for use on the Apple IIgs and potentially also other 65816-based systems. Currently, it includes implementations of AES encryption and decryption (in `lib65816crypto`), and of the MD5, SHA-1, and SHA-256 hash functions (in `lib65816hash`). The core algorithms for each of these are written in carefully optimized assembly code, and they can generally process at least several thousand bytes per second on a 2.8 MHz Apple IIgs.
This package contains libraries implementing cryptographic algorithms for the 65816, suitable for use on the Apple IIgs and potentially also other 65816-based systems. Currently, it includes implementations of AES encryption and decryption (in `lib65816crypto`), and of the MD4, MD5, SHA-1, and SHA-256 hash functions (in `lib65816hash`). The core algorithms for each of these are written in carefully optimized assembly code, and they can generally process at least several thousand bytes per second on a 2.8 MHz Apple IIgs.
Using the Libraries
-------------------
@ -11,11 +11,11 @@ If you are calling these algorithms from assembly language, simply follow the us
If you use these libraries in your program, you will need to link them into it. You can either place the libraries in the `Libraries` directory of your ORCA installation, or place them somewhere else and specify them on the command line when linking your program. When using certain algorithms (currently AES and MD5), you may also need to include `pagealign.root` as the first file on the linker command line. This file contains no code, but simply specifies that the default load segment should be page-aligned. This is needed because those algorithms include data tables that are page-aligned to maximize performance.
Note that some of the algorithms implemented in this package (including MD5 and SHA-1) have known security weaknesses. If you are using them in a situation where security is important, you should refer to up-to-date cryptanalytic results and advice to determine whether they are appropriate for your application.
Note that some of the algorithms implemented in this package (including MD4, MD5, and SHA-1) have known security weaknesses. If you are using them in a situation where security is important, you should refer to up-to-date cryptanalytic results and advice to determine whether they are appropriate for your application.
Building the Libraries
----------------------
If you want to build these libraries yourself, you will need ORCA/M and ORCA/C. To ensure everything builds correctly, I recommend using [ORCA/C 2.2.0 B1 or later][1]. The included `Makefile` is set up to build the libraries and test programs on a modern system using [Golden Gate][2], but they could also be build under the ORCA shell or GNO with a suitable build script.
If you want to build these libraries yourself, you will need ORCA/M and ORCA/C. To ensure everything builds correctly, I recommend using [ORCA/C 2.2.0 or later][1]. The included `Makefile` is set up to build the libraries and test programs on a modern system using [Golden Gate][2], but they could also be build under the ORCA shell or GNO with a suitable build script.
[1]: https://github.com/byteworksinc/ORCA-C/releases
[2]: http://golden-gate.ksherlock.com

View File

@ -21,12 +21,14 @@
#include "sha256.h"
#include "sha1.h"
#include "md5.h"
#include "md4.h"
int main(void) {
Handle context_hndl;
struct hmac_sha256_context *hmac_sha256_context;
struct hmac_sha1_context *hmac_sha1_context;
struct hmac_md5_context *hmac_md5_context;
struct hmac_md4_context *hmac_md4_context;
char key[] = "key";
char msg[] = "The quick brown fox jumps over the lazy dog";
@ -68,4 +70,15 @@ int main(void) {
printf("%02x", hmac_md5_context->u[0].ctx.hash[i]);
}
printf("\n");
hmac_md4_context = (struct hmac_md4_context *)*context_hndl;
hmac_md4_init(hmac_md4_context, key, sizeof(key)-1);
hmac_md4_compute(hmac_md4_context, msg, sizeof(msg)-1);
printf("HMAC-MD4: ");
for (int i = 0; i < sizeof(hmac_md4_context->u[0].ctx.hash); i++) {
printf("%02x", hmac_md4_context->u[0].ctx.hash[i]);
}
printf("\n");
}

153
md4.asm Normal file
View File

@ -0,0 +1,153 @@
* Copyright (c) 2017,2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* Implementation of the md4 hash function for the 65816
case on
mcopy md4.macros
* Direct page locations
length gequ 0
extra gequ 8
idx gequ 10
a_ gequ 12 ; elements of state
b gequ 16
c gequ 20
d gequ 24
zero1 gequ 28
temp gequ 30
zero2 gequ 34
;unused gequ 36
h0 gequ 40
h1 gequ 44
h2 gequ 48
h3 gequ 52
;unused gequ 56
m gequ 60
* Precomputed values of g*4 for each loop iteration, for indexing the message
; align 256
g_times_4 private
dc i2' 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60'
dc i2' 0, 16, 32, 48, 4, 20, 36, 52, 8, 24, 40, 56, 12, 28, 44, 60'
dc i2' 0, 32, 16, 48, 8, 40, 24, 56, 4, 36, 20, 52, 12, 44, 28, 60'
end
* Initialize a md4 context.
* This must be called before any of the other md4 functions.
md4_init start
CFunction MD4_INIT
end
MD4_INIT start
lda #$2301
sta h0
lda #$6745
sta h0+2
lda #$AB89
sta h1
lda #$EFCD
sta h1+2
lda #$DCFE
sta h2
lda #$98BA
sta h2+2
lda #$5476
sta h3
lda #$1032
sta h3+2
stz length
stz length+2
stz length+4
stz length+6
stz extra
stz zero1
stz zero2
rtl
end
* Process one 64-byte block through the md4 hashing function.
* This is a low-level function; users should normally not call this directly.
md4_processblock start
CFunction MD4_PROCESSBLOCK
end
MD4_PROCESSBLOCK start
lda h0
sta a_
lda h0+2
sta a_+2
lda h1
sta b
lda h1+2
sta b+2
lda h2
sta c
lda h2+2
sta c+2
lda h3
sta d
lda h3+2
sta d+2
stz idx
BlockLoopPart 1
BlockLoopPart 2
BlockLoopPart 3
clc
lda h0
adc a_
sta h0
lda h0+2
adc a_+2
sta h0+2
clc
lda h1
adc b
sta h1
lda h1+2
adc b+2
sta h1+2
clc
lda h2
adc c
sta h2
lda h2+2
adc c+2
sta h2+2
clc
lda h3
adc d
sta h3
lda h3+2
adc d+2
sta h3+2
rtl
end

141
md4.cc Normal file
View File

@ -0,0 +1,141 @@
/*
* Copyright (c) 2017,2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma noroot
#pragma lint -1
#pragma optimize -1
#include "md4.h"
#include <string.h>
#define length_offset 0
#define extra_offset 8
#define hash_offset 40
#define data_offset 60
extern void MD4_PROCESSBLOCK(void);
/*
* Update a md4 context based on the specified data.
*/
void md4_update(struct md4_context *context,
const unsigned char *data,
unsigned long length)
{
unsigned int extra = context->extra;
unsigned long oldlength = context->length;
if ((context->length += length) < oldlength)
context->length2++;
if (extra > 0) {
if (length >= 64 - extra) {
memcpy(&context->block[extra], data, 64 - extra);
asm {
phd
lda context
tcd
jsl MD4_PROCESSBLOCK
pld
}
length -= 64 - extra;
data += 64 - extra;
} else {
memcpy(&context->block[extra], data, length);
context->extra += length;
return;
}
}
while (length >= 64) {
memcpy(&context->block, data, 64);
asm {
phd
lda context
tcd
jsl MD4_PROCESSBLOCK
pld
}
length -= 64;
data += 64;
}
memcpy(&context->block, data, length);
context->extra = length;
}
/*
* Finish md4 processing and generate the final hash code.
*/
void md4_finalize(struct md4_context *context)
{
unsigned int extra = context->extra;
context->block[extra++] = 0x80;
memset(&context->block[extra], 0, 64 - extra);
if (extra > 64 - 8) {
asm {
phd
lda context
tcd
jsl MD4_PROCESSBLOCK
pld
}
memset(&context->block, 0, 64 - 8);
}
asm {
phd
lda context
tcd
/* Append total length in bits */
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
sta data_offset+56
lda length_offset+2
sta data_offset+58
lda length_offset+4
sta data_offset+60
lda length_offset+6
sta data_offset+62
/* Process final block */
jsl MD4_PROCESSBLOCK
pld
}
}
#define HASH_ALG md4
#include "hmacimpl.h"
#append "md4.asm"

77
md4.h Normal file
View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2017,2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
struct md4_context {
unsigned long length;
unsigned long length2;
unsigned short extra;
unsigned char reserved1[30];
unsigned char hash[16];
unsigned char reserved2[4];
unsigned char block[64];
};
struct hmac_md4_context {
union {
struct md4_context ctx;
unsigned char k[64];
} u[3];
unsigned char inner_hash[16];
};
/*
* The context structure must be in bank 0, preferably page-aligned.
*/
/*
* Initialize a md4 context.
* This must be called before any of the other md4 functions.
*/
void md4_init(struct md4_context *context);
/*
* Update a md4 context based on the specified data.
*/
void md4_update(struct md4_context *context, const unsigned char *data, unsigned long length);
/*
* Finish md4 processing and generate the final hash code.
*/
void md4_finalize(struct md4_context *context);
/*
* Process one 64-byte block through the md4 hashing function.
* This is a low-level function; users should normally not call this directly.
*/
void md4_processblock(struct md4_context *context);
/*
* Initialize a context for HMAC-MD4 computation with a specified key.
* This must be called before any calls to hmac_md4_compute. After
* initialization, the context can be used to compute the HMAC for any
* number of messages.
*/
void hmac_md4_init(struct hmac_md4_context *context,
const unsigned char *key,
unsigned long key_length);
/*
* Compute the HMAC-MD4 of a message, using an already-initialized context.
* The result will be in context->u[0].ctx.hash.
*/
void hmac_md4_compute(struct hmac_md4_context *context,
const unsigned char *message,
unsigned long message_length);

361
md4.macros Normal file
View File

@ -0,0 +1,361 @@
* Copyright (c) 2017,2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* Right-rotate 32-bit value in &loc (DP or 16-bit address) by &n positions
macro
ROTR4 &loc,&n
aif &n>16,.dorotl
lda &loc+2
lcla &i
&i seta &n
.rotrloop
lsr a ;to set carry
ror &loc
ror &loc+2
&i seta &i-1
aif &i>0,.rotrloop
ago .end
.dorotl
ROTL4 &loc,32-&n
.end
mend
* Expects the contents of &loc+2 to be loaded in A already
macro
ROTR4CONT &loc,&n
aif &n>16,.dorotl
lcla &i
&i seta &n
.rotrloop
lsr a ;to set carry
ror &loc
ror &loc+2
&i seta &i-1
aif &i>0,.rotrloop
ago .end
.dorotl
ROTL4 &loc,32-&n
.end
mend
* Left-rotate 32-bit value in &loc (DP or 16-bit address) by &n positions
macro
ROTL4 &loc,&n
aif &n>16,.dorotr2
lda &loc
lcla &i
&i seta &n
.rotlloop2
asl a ;to set carry
rol &loc+2
rol &loc
&i seta &i-1
aif &i>0,.rotlloop2
ago .end2
.dorotr2
ROTR4 &loc,32-&n
.end2
mend
* Expects the contents of &loc to be loaded in A already
macro
ROTL4CONT &loc,&n
aif &n>16,.dorotr2
lcla &i
&i seta &n
.rotlloop2
asl a ;to set carry
rol &loc+2
rol &loc
&i seta &i-1
aif &i>0,.rotlloop2
ago .end2
.dorotr2
ROTR4 &loc,32-&n
.end2
mend
* &to := &from ROTR4 &n
macro
ROTR4MOVE &to,&from,&n
aif &n>16,.dorotl3
lda &from
sta &to
lda &from+2
sta &to+2
lcla &i
&i seta &n
.rotrloop3
lsr a ;to set carry
ror &to
ror &to+2
&i seta &i-1
aif &i>0,.rotrloop3
ago .end3
.dorotl3
ROTL4MOVE &to,&from,32-&n
.end3
mend
* &to := &from ROTL4 &n
macro
ROTL4MOVE &to,&from,&n
aif &n>16,.dorotr4
lda &from+2
sta &to+2
lda &from
sta &to
lcla &i
&i seta &n
.rotlloop4
asl a ;to set carry
rol &to+2
rol &to
&i seta &i-1
aif &i>0,.rotlloop4
ago .end4
.dorotr4
ROTR4MOVE &to,&from,32-&n
.end4
mend
* Left-rotate with various optimizations applied
macro
ROTL4AUTO &loc,&n,&haveLocPlus2
aif &n>4,.skip1
ROTL4 &loc,&n
mexit
.skip1
aif &n>7,.skip2
ldx &loc+1
lda &loc+3
ora &loc-1
sta &loc
stx &loc+2
txa
ROTR4CONT &loc,8-&n
mexit
.skip2
aif &n>11,.skip3
ldx &loc+1
lda &loc+3
ora &loc-1
sta &loc
stx &loc+2
ROTL4CONT &loc,&n-8
mexit
.skip3
aif &n>15,.skip4
aif C:&haveLocPlus2>0,.noload1
ldy &loc+2
ago .didload1
.noload1
tay
.didload1
lda &loc
sta &loc+2
sty &loc
ROTR4CONT &loc,16-&n
mexit
.skip4
aif &n>16,.skip5
aif C:&haveLocPlus2>0,.noload2
lda &loc+2
.noload2
ldy &loc
sta &loc
sty &loc+2
mexit
.skip5
aif &n>20,.skip6
aif C:&haveLocPlus2>0,.noload2
lda &loc+2
.noload2
ldy &loc
sta &loc
sty &loc+2
ROTL4CONT &loc,&n-16
mexit
.skip6
ldx &loc+1
lda &loc+3
ora &loc-1
sta &loc+2
stx &loc
ROTR4CONT &loc,24-&n
mend
* This makes a function wrapper that is callable from C,
* taking a pointer to the context structure as its argument.
macro
CFunction &fn
phb
plx
ply
tdc
pld
plb
plb
phy
phx
plb
pha
jsl &fn
pld
rtl
mend
* One iteration of the loop for processing blocks.
* The a,b,c,d variables are given as parameters so we can avoid cycling them.
* shift is a per-round shift amount.
macro
BlockLoopIter &a,&b,&c,&d,&shift
* f_0 to f_15
aif &part<>1,.skip1
lda &c
eor &d
and &b
eor &d
clc
adc &a
sta temp
lda &c+2
eor &d+2
and &b+2
eor &d+2
adc &a+2
sta temp+2
.skip1
* f_16 to f_31
aif &part<>2,.skip2
lda &c
tax
ora &d
and &b
sta temp
txa
and &d
ora temp
clc
adc &a
tay
lda &c+2
tax
ora &d+2
and &b+2
sta temp+2
txa
and &d+2
ora temp+2
adc &a+2
tax
clc
tya
adc #$7999
sta temp
txa
adc #$5A82
sta temp+2
.skip2
* f_32 to f_47
aif &part<>3,.skip3
lda &b
eor &c
eor &d
clc
adc &a
tay
lda &b+2
eor &c+2
eor &d+2
adc &a+2
tax
clc
tya
adc #$EBA1
sta temp
txa
adc #$6ED9
sta temp+2
.skip3
ldy idx
ldx g_times_4,y
lda m,x
clc
adc temp
sta temp
inx
inx
lda m,x
adc temp+2
sta temp+2
iny
iny
sty idx
ROTL4AUTO temp,&shift,1
lda temp
sta &a
lda temp+2
sta &a+2
mend
* One part of the loop for processing blocks (16 iterations)
macro
BlockLoopPart &part
loop&part anop
aif &part<>1,.skip1a
BlockLoopIter a_,b,c,d,3
BlockLoopIter d,a_,b,c,7
BlockLoopIter c,d,a_,b,11
BlockLoopIter b,c,d,a_,19
.skip1a
aif &part<>2,.skip2a
BlockLoopIter a_,b,c,d,3
BlockLoopIter d,a_,b,c,5
BlockLoopIter c,d,a_,b,9
BlockLoopIter b,c,d,a_,13
.skip2a
aif &part<>3,.skip3a
BlockLoopIter a_,b,c,d,3
BlockLoopIter d,a_,b,c,9
BlockLoopIter c,d,a_,b,11
BlockLoopIter b,c,d,a_,15
.skip3a
lda idx
cmp #16*2*&part
bge endloop&part
jmp loop&part
endloop&part anop
mend

20
md4sum.c Normal file
View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2017,2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "md4.h"
#define HASH_FUNCTION md4
#include "cksumcommon.h"

94
md4test.c Normal file
View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2017,2023 Stephen Heumann
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "md4.h"
#include <stdio.h>
#include <MiscTool.h>
#include <Memory.h>
#include <orca.h>
#include <string.h>
int main(int argc, char **argv) {
unsigned int i;
unsigned long tick_count;
long double bytes_per_sec;
struct md4_context *context, **context_hndl;
struct md4_context context_init = {0,0,0, {0}, {0}, {0},
{0x61,0x62,0x63,0x80,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,
0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00
}};
context_hndl = (struct md4_context **)NewHandle(sizeof(struct md4_context),
userid(), attrFixed|attrPage|attrBank|attrNoCross, 0x000000);
if (toolerror())
return 0;
context = *context_hndl;
*context = context_init;
md4_init(context);
md4_processblock(context);
printf("h[..] = %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]);
tick_count = GetTick();
for (i = 0; i < 1000; i++) {
md4_processblock(context);
}
tick_count = GetTick() - tick_count;
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();
md4_init(context);
md4_update(context, (void*)0x030000, 64000);
md4_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) {
md4_init(context);
md4_update(context, argv[1], strlen(argv[1]));
md4_finalize(context);
printf("h[..] = %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]);
}
}