Skip to content
This repository has been archived by the owner on Jul 24, 2020. It is now read-only.

Commit

Permalink
MD5 added
Browse files Browse the repository at this point in the history
  • Loading branch information
kayceesrk committed Oct 20, 2011
1 parent a625295 commit 89e1144
Show file tree
Hide file tree
Showing 5 changed files with 347 additions and 0 deletions.
47 changes: 47 additions & 0 deletions trunk/testing/benchmarks/MD5/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash

DEBUG := false
PROFILE := no
STACK := false
BRANCH := false
MORE :=

SRCS := $(wildcard *.sml)
SRC_RULS := $(subst .sml,-amd64,$(SRCS))

MMPATH = $(HOME)/PLDI/multiMLton-UT
MULTIMLTON= $(MMPATH)/trunk/build/bin/mlton

%-amd64 : $(SRCS)
$(MULTIMLTON) $(MORE) -keep g -debug $(DEBUG) -profile $(PROFILE) -profile-stack $(STACK) -profile-branch $(BRANCH) -output $@ "$(subst -amd64,,$@).sml"

all: $(SRC_RULS)

clean:
rm -rf $(SRC_RULS) *~ op *.out *.c *ssa *ssa2 *xml *-ml *machine

clean-summaries:
rm gc-summary.*


FLAGS = -std=gnu99 -c -g -DASSERT=1 -I$(MMPATH)/trunk/build/lib/self/include \
-I$(MMPATH)/trunk/build/lib/include -O1 -fno-common -fno-strict-aliasing \
-fomit-frame-pointer -w -m64

DEBUG_LIBS = -L$(MMPATH)/trunk/build/lib/self -lmlton-gdb -lgdtoa-gdb \
-lm -lgmp -m64 -lplpa_included -pthread -lrt

LIBS = -L$(MMPATH)/trunk/build/lib/self -lmlton -lgdtoa \
-lm -lgmp -m64 -lplpa_included -pthread -lrt

%.o: %.c
gcc $(FLAGS) -o $@ $<

.SECONDEXPANSION:
%-c : $$(subst .c,.o,$$(wildcard $$(subst -c,,$$@).*.c))
gcc -o $(subst -c,,$@) $^ $(LIBS)


.SECONDEXPANSION:
%-cdebug : $$(subst .c,.o,$$(wildcard $$(subst -cdebug,,$$@).*.c))
gcc -o $(subst -cdebug,,$@) $^ $(DEBUG_LIBS)
294 changes: 294 additions & 0 deletions trunk/testing/benchmarks/MD5/md5.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
(* Copyright (C) 2001 Daniel Wang. All rights reserved.
Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm.
*)
signature MD5 =
sig
type md5state
(* type slice = (Word8Vector.vector * int * int option) *)
val init : md5state
(* val updateSlice : (md5state * slice) -> md5state
*)
val update : (md5state * Word8Vector.vector) -> md5state
val final : md5state -> Word8Vector.vector
val toHexString : Word8Vector.vector -> string
end

(* Quick and dirty transliteration of C code *)
structure MD5 :> MD5 =
struct
structure W32 = Word32
structure W8V =
struct
open Word8Vector
fun extract (vec, s, l) =
let
val n =
case l of
NONE => length vec - s
| SOME i => i
in
tabulate (n, fn i => sub (vec, s + i))
end
end
type word64 = {hi:W32.word,lo:W32.word}
type word128 = {A:W32.word, B:W32.word, C:W32.word, D:W32.word}
type md5state = {digest:word128,
mlen:word64,
buf:Word8Vector.vector}



val w64_zero = ({hi=0w0,lo=0w0}:word64)
fun mul8add ({hi,lo},n) = let
val mul8lo = W32.<< (W32.fromInt (n),0w3)
val mul8hi = W32.>> (W32.fromInt (n),0w29)
val lo = W32.+ (lo,mul8lo)
val cout = if W32.< (lo,mul8lo) then 0w1 else 0w0
val hi = W32.+ (mul8hi,W32.+ (hi,cout))
in {hi=hi,lo=lo}
end

fun packLittle wrds = let
fun loop [] = []
| loop (w::ws) = let
val b0 = Word8.fromLarge (W32.toLarge w)
val b1 = Word8.fromLarge (W32.toLarge (W32.>> (w,0w8)))
val b2 = Word8.fromLarge (W32.toLarge (W32.>> (w,0w16)))
val b3 = Word8.fromLarge (W32.toLarge (W32.>> (w,0w24)))
in b0::b1::b2::b3:: (loop ws)
end
in W8V.fromList (loop wrds)
end

val S11 = 0w7
val S12 = 0w12
val S13 = 0w17
val S14 = 0w22
val S21 = 0w5
val S22 = 0w9
val S23 = 0w14
val S24 = 0w20
val S31 = 0w4
val S32 = 0w11
val S33 = 0w16
val S34 = 0w23
val S41 = 0w6
val S42 = 0w10
val S43 = 0w15
val S44 = 0w21

fun PADDING i = W8V.tabulate (i,(fn 0 => 0wx80 | _ => 0wx0))

fun F (x,y,z) = W32.orb (W32.andb (x,y),
W32.andb (W32.notb x,z))
fun G (x,y,z) = W32.orb (W32.andb (x,z),
W32.andb (y,W32.notb z))
fun H (x,y,z) = W32.xorb (x,W32.xorb (y,z))
fun I (x,y,z) = W32.xorb (y,W32.orb (x,W32.notb z))
fun ROTATE_LEFT (x,n) =
W32.orb (W32.<< (x,n), W32.>> (x,0w32 - n))

fun XX f (a,b,c,d,x,s,ac) = let
val a = W32.+ (a,W32.+ (W32.+ (f (b,c,d),x),ac))
val a = ROTATE_LEFT (a,s)
in W32.+ (a,b)
end

val FF = XX F
val GG = XX G
val HH = XX H
val II = XX I

val empty_buf = W8V.tabulate (0,(fn x => raise (Fail "buf")))
val init = {digest= {A=0wx67452301,
B=0wxefcdab89,
C=0wx98badcfe,
D=0wx10325476},
mlen=w64_zero,
buf=empty_buf} : md5state

fun update ({buf,digest,mlen}:md5state,input) = let
val inputLen = W8V.length input
val needBytes = 64 - W8V.length buf
fun loop (i,digest) =
if i + 63 < inputLen then
loop (i + 64,transform (digest,i,input))
else (i,digest)
val (buf,(i,digest)) =
if inputLen >= needBytes then let
val buf = W8V.concat [buf,W8V.extract (input,0,SOME needBytes)]
val digest = transform (digest,0,buf)
in (empty_buf,loop (needBytes,digest))
end
else (buf,(0,digest))
val buf = W8V.concat [buf, W8V.extract (input,i,SOME (inputLen-i))]
val mlen = mul8add (mlen,inputLen)
in {buf=buf,digest=digest,mlen=mlen}
end
and final (state:md5state) = let
val {mlen= {lo,hi},buf,...} = state
val bits = packLittle [lo,hi]
val index = W8V.length buf
val padLen = if index < 56 then 56 - index else 120 - index
val state = update (state,PADDING padLen)
val {digest= {A,B,C,D},...} = update (state,bits)
in packLittle [A,B,C,D]
end
and transform ({A,B,C,D},i,buf) = let
val off = i div PackWord32Little.bytesPerElem
fun x (n) = Word32.fromLarge (PackWord32Little.subVec (buf,n + off))
val (a,b,c,d) = (A,B,C,D)
(* fetch to avoid range checks *)
val x_00 = x (0) val x_01 = x (1) val x_02 = x (2) val x_03 = x (3)
val x_04 = x (4) val x_05 = x (5) val x_06 = x (6) val x_07 = x (7)
val x_08 = x (8) val x_09 = x (9) val x_10 = x (10) val x_11 = x (11)
val x_12 = x (12) val x_13 = x (13) val x_14 = x (14) val x_15 = x (15)

val a = FF (a, b, c, d, x_00, S11, 0wxd76aa478) (* 1 *)
val d = FF (d, a, b, c, x_01, S12, 0wxe8c7b756) (* 2 *)
val c = FF (c, d, a, b, x_02, S13, 0wx242070db) (* 3 *)
val b = FF (b, c, d, a, x_03, S14, 0wxc1bdceee) (* 4 *)
val a = FF (a, b, c, d, x_04, S11, 0wxf57c0faf) (* 5 *)
val d = FF (d, a, b, c, x_05, S12, 0wx4787c62a) (* 6 *)
val c = FF (c, d, a, b, x_06, S13, 0wxa8304613) (* 7 *)
val b = FF (b, c, d, a, x_07, S14, 0wxfd469501) (* 8 *)
val a = FF (a, b, c, d, x_08, S11, 0wx698098d8) (* 9 *)
val d = FF (d, a, b, c, x_09, S12, 0wx8b44f7af) (* 10 *)
val c = FF (c, d, a, b, x_10, S13, 0wxffff5bb1) (* 11 *)
val b = FF (b, c, d, a, x_11, S14, 0wx895cd7be) (* 12 *)
val a = FF (a, b, c, d, x_12, S11, 0wx6b901122) (* 13 *)
val d = FF (d, a, b, c, x_13, S12, 0wxfd987193) (* 14 *)
val c = FF (c, d, a, b, x_14, S13, 0wxa679438e) (* 15 *)
val b = FF (b, c, d, a, x_15, S14, 0wx49b40821) (* 16 *)

(* Round 2 *)
val a = GG (a, b, c, d, x_01, S21, 0wxf61e2562) (* 17 *)
val d = GG (d, a, b, c, x_06, S22, 0wxc040b340) (* 18 *)
val c = GG (c, d, a, b, x_11, S23, 0wx265e5a51) (* 19 *)
val b = GG (b, c, d, a, x_00, S24, 0wxe9b6c7aa) (* 20 *)
val a = GG (a, b, c, d, x_05, S21, 0wxd62f105d) (* 21 *)
val d = GG (d, a, b, c, x_10, S22, 0wx2441453) (* 22 *)
val c = GG (c, d, a, b, x_15, S23, 0wxd8a1e681) (* 23 *)
val b = GG (b, c, d, a, x_04, S24, 0wxe7d3fbc8) (* 24 *)
val a = GG (a, b, c, d, x_09, S21, 0wx21e1cde6) (* 25 *)
val d = GG (d, a, b, c, x_14, S22, 0wxc33707d6) (* 26 *)
val c = GG (c, d, a, b, x_03, S23, 0wxf4d50d87) (* 27 *)
val b = GG (b, c, d, a, x_08, S24, 0wx455a14ed) (* 28 *)
val a = GG (a, b, c, d, x_13, S21, 0wxa9e3e905) (* 29 *)
val d = GG (d, a, b, c, x_02, S22, 0wxfcefa3f8) (* 30 *)
val c = GG (c, d, a, b, x_07, S23, 0wx676f02d9) (* 31 *)
val b = GG (b, c, d, a, x_12, S24, 0wx8d2a4c8a) (* 32 *)

(* Round 3 *)
val a = HH (a, b, c, d, x_05, S31, 0wxfffa3942) (* 33 *)
val d = HH (d, a, b, c, x_08, S32, 0wx8771f681) (* 34 *)
val c = HH (c, d, a, b, x_11, S33, 0wx6d9d6122) (* 35 *)
val b = HH (b, c, d, a, x_14, S34, 0wxfde5380c) (* 36 *)
val a = HH (a, b, c, d, x_01, S31, 0wxa4beea44) (* 37 *)
val d = HH (d, a, b, c, x_04, S32, 0wx4bdecfa9) (* 38 *)
val c = HH (c, d, a, b, x_07, S33, 0wxf6bb4b60) (* 39 *)
val b = HH (b, c, d, a, x_10, S34, 0wxbebfbc70) (* 40 *)
val a = HH (a, b, c, d, x_13, S31, 0wx289b7ec6) (* 41 *)
val d = HH (d, a, b, c, x_00, S32, 0wxeaa127fa) (* 42 *)
val c = HH (c, d, a, b, x_03, S33, 0wxd4ef3085) (* 43 *)
val b = HH (b, c, d, a, x_06, S34, 0wx4881d05) (* 44 *)
val a = HH (a, b, c, d, x_09, S31, 0wxd9d4d039) (* 45 *)
val d = HH (d, a, b, c, x_12, S32, 0wxe6db99e5) (* 46 *)
val c = HH (c, d, a, b, x_15, S33, 0wx1fa27cf8) (* 47 *)
val b = HH (b, c, d, a, x_02, S34, 0wxc4ac5665) (* 48 *)

(* Round 4 *)
val a = II (a, b, c, d, x_00, S41, 0wxf4292244) (* 49 *)
val d = II (d, a, b, c, x_07, S42, 0wx432aff97) (* 50 *)
val c = II (c, d, a, b, x_14, S43, 0wxab9423a7) (* 51 *)
val b = II (b, c, d, a, x_05, S44, 0wxfc93a039) (* 52 *)
val a = II (a, b, c, d, x_12, S41, 0wx655b59c3) (* 53 *)
val d = II (d, a, b, c, x_03, S42, 0wx8f0ccc92) (* 54 *)
val c = II (c, d, a, b, x_10, S43, 0wxffeff47d) (* 55 *)
val b = II (b, c, d, a, x_01, S44, 0wx85845dd1) (* 56 *)
val a = II (a, b, c, d, x_08, S41, 0wx6fa87e4f) (* 57 *)
val d = II (d, a, b, c, x_15, S42, 0wxfe2ce6e0) (* 58 *)
val c = II (c, d, a, b, x_06, S43, 0wxa3014314) (* 59 *)
val b = II (b, c, d, a, x_13, S44, 0wx4e0811a1) (* 60 *)
val a = II (a, b, c, d, x_04, S41, 0wxf7537e82) (* 61 *)
val d = II (d, a, b, c, x_11, S42, 0wxbd3af235) (* 62 *)
val c = II (c, d, a, b, x_02, S43, 0wx2ad7d2bb) (* 63 *)
val b = II (b, c, d, a, x_09, S44, 0wxeb86d391) (* 64 *)

val A = Word32.+ (A,a)
val B = Word32.+ (B,b)
val C = Word32.+ (C,c)
val D = Word32.+ (D,d)
in {A=A,B=B,C=C,D=D}
end

val hxd = "0123456789abcdef"
fun toHexString v = let
fun byte2hex (b,acc) =
(String.sub (hxd,(Word8.toInt b) div 16))::
(String.sub (hxd,(Word8.toInt b) mod 16))::acc
val digits = Word8Vector.foldr byte2hex [] v
in String.implode (digits)
end
end

structure Test =
struct
val tests =
[("", "d41d8cd98f00b204e9800998ecf8427e"),
("a", "0cc175b9c0f1b6a831c399e269772661"),
("abc", "900150983cd24fb0d6963f7d28e17f72"),
("message digest", "f96b697d7cb7938d525a2f31aaf161d0"),
("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b"),
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"d174ab98d277d9f5a5611c2c9f419d9f"),
("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"57edf4a22be3c955ac49da2e2107b67a")]

fun do_tests () = let
fun f (x,s) = let
val mstate = MD5.update (MD5.init,Byte.stringToBytes x)
val hash = MD5.final (mstate)
in print (" input: "^x^"\n");
print ("expected: "^s^"\n");
print ("produced: "^MD5.toHexString (hash)^"\n")
end
in List.app f tests
end
val BLOCK_LEN = 10000
val BLOCK_COUNT = 100000
fun time_test () = let
val block = Word8Vector.tabulate (BLOCK_LEN,Word8.fromInt)
fun loop (n,s) =
if n < BLOCK_COUNT then
loop (n+1,MD5.update (s,block))
else s
in
loop (0,MD5.init)
end
end

structure Main =
struct
fun doit n =
if n = 0
then ()
else (MLton.Pacml.spawn (fn () => ignore (Test.time_test ()))
; doit (n - 1))
end

val numThreads = case CommandLine.arguments () of
s1::_ => (case Int.fromString s1 of
SOME n => n
| _ => 30)
| _ => 30

val ts = Time.now ()
val _ = TextIO.print (concat ["Starting main\n"])
val _ = TextIO.print (concat ["numThreads = ", Int.toString numThreads, "\n"])
val _ = MLton.Pacml.run (fn () => Main.doit (numThreads))
val te = Time.now ()
val d = Time.-(te, ts)
val _ = TextIO.print (concat ["Time start: ", Time.toString ts, "\n"])
val _ = TextIO.print (concat ["Time end: ", Time.toString te, "\n"])
val _ = TextIO.print (concat ["Time diff: ", LargeInt.toString (Time.toMilliseconds d), "ms\n"])
2 changes: 2 additions & 0 deletions trunk/testing/benchmarks/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def fullParameters():
"KClustering": "kclustering-amd64", \
"TSP2": "tsp-amd64", \
"Nucleic": "nucleic-amd64", \
"MD5": "md5-amd64", \
"CountGraphs": "count-graphs-amd64", \
"GameOfLife": "lifeM-amd64", \
"Mergesort": "mergesort-amd64", \
Expand All @@ -120,6 +121,7 @@ def fullParameters():
"KClustering": "0 50 700 70 0", \
"TSP2": "", \
"Nucleic": "512", \
"MD5": "16", \
"CountGraphs": "1", \
"GameOfLife": "64 300", \
"Mergesort": "10000", \
Expand Down
2 changes: 2 additions & 0 deletions trunk/testing/benchmarks/findHeapValues.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def fullParameters():
"KClustering": "kclustering-amd64", \
"TSP2": "tsp-amd64", \
"Nucleic": "nucleic-amd64", \
"MD5": "md5-amd64", \
"CountGraphs": "count-graphs-amd64", \
"GameOfLife": "lifeM-amd64", \
"Mergesort": "mergesort-amd64", \
Expand All @@ -137,6 +138,7 @@ def fullParameters():
"KClustering": "0 50 700 70 0", \
"TSP2": "", \
"Nucleic": "512", \
"MD5": "16", \
"CountGraphs": "1", \
"GameOfLife": "64 300", \
"Mergesort": "10000", \
Expand Down
2 changes: 2 additions & 0 deletions trunk/testing/benchmarks/runBench.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def fullParameters():
"KClustering": "kclustering-amd64", \
"TSP2": "tsp-amd64", \
"Nucleic": "nucleic-amd64", \
"MD5": "md5-amd64", \
"CountGraphs": "count-graphs-amd64", \
"GameOfLife": "lifeM-amd64", \
"Mergesort": "mergesort-amd64", \
Expand All @@ -135,6 +136,7 @@ def fullParameters():
"KClustering": "0 50 700 70 0", \
"TSP2": "", \
"Nucleic": "512", \
"MD5": "16", \
"CountGraphs": "1", \
"GameOfLife": "64 300", \
"Mergesort": "10000", \
Expand Down

0 comments on commit 89e1144

Please sign in to comment.