September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
123
Task/MD5-Implementation/Common-Lisp/md5-implementation.lisp
Normal file
123
Task/MD5-Implementation/Common-Lisp/md5-implementation.lisp
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
(defpackage #:md5
|
||||
(:use #:cl))
|
||||
|
||||
(in-package #:md5)
|
||||
|
||||
(require :babel)
|
||||
|
||||
(deftype word () '(unsigned-byte 32))
|
||||
(deftype octet () '(unsigned-byte 8))
|
||||
(deftype octets () '(vector octet))
|
||||
|
||||
(defparameter *s*
|
||||
(make-array 16 :element-type 'word
|
||||
:initial-contents '(7 12 17 22
|
||||
5 9 14 20
|
||||
4 11 16 23
|
||||
6 10 15 21)))
|
||||
|
||||
(defun s (i)
|
||||
(declare ((integer 0 63) i))
|
||||
(aref *s* (+ (ash (ash i -4) 2)
|
||||
(ldb (byte 2 0) i))))
|
||||
|
||||
(defparameter *k*
|
||||
(loop with result = (make-array 64 :element-type 'word)
|
||||
for i from 0 below 64
|
||||
do (setf (aref result i) (floor (* (ash 1 32) (abs (sin (1+ (float i 1d0)))))))
|
||||
finally (return result)))
|
||||
|
||||
(defun wrap (bits integer)
|
||||
(declare (fixnum bits) (integer integer))
|
||||
(ldb (byte bits 0) integer))
|
||||
|
||||
(defun integer->8octets (integer)
|
||||
(declare (integer integer))
|
||||
(loop for n = (wrap 64 integer) then (ash n -8)
|
||||
repeat 8
|
||||
collect (wrap 8 n)))
|
||||
|
||||
(defun pad-octets (octets)
|
||||
(declare (octets octets))
|
||||
(let* ((octets-length (length octets))
|
||||
(zero-pad-length (- 64 (mod (+ octets-length 9) 64)))
|
||||
(zero-pads (loop repeat zero-pad-length collect 0)))
|
||||
(concatenate 'octets octets '(#x80) zero-pads (integer->8octets (* 8 octets-length)))))
|
||||
|
||||
(defun octets->words (octets)
|
||||
(declare (octets octets))
|
||||
(loop with result = (make-array (/ (length octets) 4) :element-type 'word)
|
||||
for n from 0 below (length octets) by 4
|
||||
for i from 0
|
||||
do (setf (aref result i)
|
||||
(dpb (aref octets (+ n 3)) (byte 8 24)
|
||||
(dpb (aref octets (+ n 2)) (byte 8 16)
|
||||
(dpb (aref octets (1+ n)) (byte 8 8)
|
||||
(dpb (aref octets n) (byte 8 0) 0)))))
|
||||
finally (return result)))
|
||||
|
||||
(defun words->octets (&rest words)
|
||||
(loop for word of-type word in words
|
||||
collect (ldb (byte 8 0) word)
|
||||
collect (ldb (byte 8 8) word)
|
||||
collect (ldb (byte 8 16) word)
|
||||
collect (ldb (byte 8 24) word)))
|
||||
|
||||
(defun left-rotate (x c)
|
||||
(declare (integer x) (fixnum c))
|
||||
(let ((x (wrap 32 x)))
|
||||
(wrap 32 (logior (ash x c)
|
||||
(ash x (- c 32))))))
|
||||
|
||||
(defun md5 (string)
|
||||
(declare (string string))
|
||||
(loop with m = (octets->words (pad-octets (babel:string-to-octets string)))
|
||||
with a0 of-type word = #x67452301
|
||||
with b0 of-type word = #xefcdab89
|
||||
with c0 of-type word = #x98badcfe
|
||||
with d0 of-type word = #x10325476
|
||||
for j from 0 below (length m) by 16
|
||||
do (loop for a of-type word = a0 then d
|
||||
and b of-type word = b0 then new-b
|
||||
and c of-type word = c0 then b
|
||||
and d of-type word = d0 then c
|
||||
for i from 0 below 64
|
||||
for new-b = (multiple-value-bind (f g)
|
||||
(ecase (ash i -4)
|
||||
(0 (values (wrap 32 (logior (logand b c)
|
||||
(logand (lognot b) d)))
|
||||
i))
|
||||
(1 (values (wrap 32 (logior (logand d b)
|
||||
(logand (lognot d) c)))
|
||||
(wrap 4 (1+ (* 5 i)))))
|
||||
(2 (values (wrap 32 (logxor b c d))
|
||||
(wrap 4 (+ (* 3 i) 5))))
|
||||
(3 (values (wrap 32 (logxor c
|
||||
(logior b (lognot d))))
|
||||
(wrap 4 (* 7 i)))))
|
||||
(declare (word f g))
|
||||
(wrap 32 (+ b (left-rotate (+ a f (aref *k* i) (aref m (+ j g)))
|
||||
(s i)))))
|
||||
finally (setf a0 (wrap 32 (+ a0 a))
|
||||
b0 (wrap 32 (+ b0 b))
|
||||
c0 (wrap 32 (+ c0 c))
|
||||
d0 (wrap 32 (+ d0 d))))
|
||||
finally (return (with-output-to-string (s)
|
||||
(dolist (o (words->octets a0 b0 c0 d0))
|
||||
(format s "~(~2,'0X~)" o))))))
|
||||
|
||||
(defun test-cases ()
|
||||
(assert (string= "d41d8cd98f00b204e9800998ecf8427e"
|
||||
(md5 "")))
|
||||
(assert (string= "0cc175b9c0f1b6a831c399e269772661"
|
||||
(md5 "a")))
|
||||
(assert (string= "900150983cd24fb0d6963f7d28e17f72"
|
||||
(md5 "abc")))
|
||||
(assert (string= "f96b697d7cb7938d525a2f31aaf161d0"
|
||||
(md5 "message digest")))
|
||||
(assert (string= "c3fcd3d76192e4007dfb496cca67e13b"
|
||||
(md5 "abcdefghijklmnopqrstuvwxyz")))
|
||||
(assert (string= "d174ab98d277d9f5a5611c2c9f419d9f"
|
||||
(md5 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")))
|
||||
(assert (string= "57edf4a22be3c955ac49da2e2107b67a"
|
||||
(md5 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"))))
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
module md5asm ;
|
||||
import std.string ;
|
||||
import std.conv ;
|
||||
import std.math ;
|
||||
|
||||
version(D_InlineAsm_X86) {} else { static assert(0,"For X86 machine only") ; }
|
||||
|
||||
// ctfe construction of transform expressions
|
||||
uint S(uint n) {
|
||||
return [7u,12,17,22,5,9,14,20,4,11,16,23,6,10,15,21][(n/16)*4 + (n % 4)] ;
|
||||
}
|
||||
uint K(uint n) {
|
||||
return ((n<=15)? n : (n <=31) ? 5*n+1 : (n<=47) ? (3*n+5) : (7*n)) % 16 ;
|
||||
}
|
||||
uint T(uint n) { return cast(uint) (abs(sin(n+1.0L))*(2UL^^32)) ; }
|
||||
enum abcd = ["EAX", "EBX", "ECX", "EDX"] ;
|
||||
string[] ABCD(int n) { return abcd[(64 - n)%4..4] ~ abcd[0..(64 - n)%4] ; }
|
||||
string SUB(int n, string s) {
|
||||
return s.replace("ax", ABCD(n)[0]).replace("bx", ABCD(n)[1]).
|
||||
replace("cx", ABCD(n)[2]).replace("dx", ABCD(n)[3]) ;
|
||||
}
|
||||
// FF, GG, HH & II expressions part 1 (F,G,H,I)
|
||||
string fghi1(int n) {
|
||||
switch(n / 16) {
|
||||
case 0: return // (bb & cc)|(~bb & dd)
|
||||
q{mov ESI,bx;mov EDI,bx;not ESI;and EDI,cx;and ESI,dx;or EDI,ESI;add ax,EDI;} ;
|
||||
case 1: return // (dd & bb)|(~dd & cc)
|
||||
q{mov ESI,dx;mov EDI,dx;not ESI;and EDI,bx;and ESI,cx;or EDI,ESI;add ax,EDI;} ;
|
||||
case 2: return // (bb ^ cc ^ dd)
|
||||
q{mov EDI,bx;xor EDI,cx;xor EDI,dx;add ax,EDI;} ;
|
||||
case 3: return // (cc ^ (bb | ~dd))
|
||||
q{mov EDI,dx;not EDI;or EDI,bx;xor EDI,cx;add ax,EDI;} ;
|
||||
}
|
||||
}
|
||||
// FF, GG, HH & II expressions part 2
|
||||
string fghi2(int n) { return q{add ax,[EBP + 4*KK];add ax,TT;} ~ fghi1(n) ; }
|
||||
// FF, GG, HH & II expressions prepended with previous parts & subsitute ABCD
|
||||
string FGHI(int n) {
|
||||
return SUB(n, fghi2(n) ~ q{rol ax,SS;add ax,bx;}) ;
|
||||
// aa = ((aa << SS)|( aa >>> (32 - SS))) + bb = ROL(aa, SS) + bb
|
||||
}
|
||||
string EXPR(uint n) {
|
||||
return FGHI(n).replace("SS", to!string(S(n))).
|
||||
replace("KK", to!string(K(n))).
|
||||
replace("TT", "0x"~to!string(T(n),16)) ;
|
||||
}
|
||||
string TRANSFORM(int n) { return (n < 63) ? EXPR(n) ~ TRANSFORM(n+1) : EXPR(n) ; }
|
||||
|
||||
// main steps of transform , to be mixing
|
||||
const string Transform = TRANSFORM(0) ;
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
module zmd5 ;
|
||||
private import md5asm ;
|
||||
|
||||
/*
|
||||
duplicated codes from standard module
|
||||
*/
|
||||
|
||||
private void transform(ubyte* block) {
|
||||
|
||||
uint[16] x;
|
||||
|
||||
Decode (x.ptr, block, 64);
|
||||
|
||||
auto pState = state.ptr ;
|
||||
auto pBuffer = x.ptr ;
|
||||
|
||||
asm{
|
||||
mov ESI, pState[EBP] ;
|
||||
mov EDX,[ESI + 3*4] ;
|
||||
mov ECX,[ESI + 2*4] ;
|
||||
mov EBX,[ESI + 1*4] ;
|
||||
mov EAX,[ESI + 0*4] ;
|
||||
push EBP ;
|
||||
push ESI ;
|
||||
|
||||
mov EBP, pBuffer[EBP] ;
|
||||
}
|
||||
|
||||
mixin("asm { "~md5asm.Transform~"}") ;
|
||||
|
||||
asm{
|
||||
pop ESI ;
|
||||
pop EBP ;
|
||||
add [ESI + 0*4],EAX ;
|
||||
add [ESI + 1*4],EBX ;
|
||||
add [ESI + 2*4],ECX ;
|
||||
add [ESI + 3*4],EDX ;
|
||||
}
|
||||
x[] = 0 ;
|
||||
}
|
||||
|
||||
/*
|
||||
duplicated codes from standard module
|
||||
*/
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
import std.stdio ;
|
||||
import std.perf ;
|
||||
private import std.md5 ;
|
||||
private import zmd5 ;
|
||||
private import md5asm ;
|
||||
|
||||
void main() {
|
||||
writefln("digest(\"\") = %s", std.md5.getDigestString("")) ;
|
||||
writefln("digest(\"\") = %s", zmd5.getDigestString("")) ;
|
||||
|
||||
const MBytes = 512 ;
|
||||
float[] MSG = new float[](MBytes * 0x40000 + 13) ;
|
||||
auto pf = new PerformanceCounter ;
|
||||
|
||||
writefln("\nTest performance / message size %dMBytes", MBytes) ;
|
||||
pf.start() ; writefln("digest(MSG) = %s", std.md5.getDigestString(MSG)) ;
|
||||
pf.stop() ; auto time = pf.milliseconds/1000.0 ;
|
||||
writefln("std.md5 : %8.2f M/sec ( %8.2fsecs)", MBytes/time, time) ;
|
||||
|
||||
pf.start() ; writefln("digest(MSG) = %s", zmd5.getDigestString(MSG)) ;
|
||||
pf.stop() ; time = pf.milliseconds/1000.0 ;
|
||||
writefln("zmd5 : %8.2f M/sec ( %8.2fsecs)", MBytes/time, time) ;
|
||||
}
|
||||
130
Task/MD5-Implementation/Kotlin/md5-implementation.kotlin
Normal file
130
Task/MD5-Implementation/Kotlin/md5-implementation.kotlin
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
// version 1.1.3
|
||||
|
||||
object MD5 {
|
||||
|
||||
private val INIT_A = 0x67452301
|
||||
private val INIT_B = 0xEFCDAB89L.toInt()
|
||||
private val INIT_C = 0x98BADCFEL.toInt()
|
||||
private val INIT_D = 0x10325476
|
||||
|
||||
private val SHIFT_AMTS = intArrayOf(
|
||||
7, 12, 17, 22,
|
||||
5, 9, 14, 20,
|
||||
4, 11, 16, 23,
|
||||
6, 10, 15, 21
|
||||
)
|
||||
|
||||
private val TABLE_T = IntArray(64) {
|
||||
((1L shl 32) * Math.abs(Math.sin(it + 1.0))).toLong().toInt()
|
||||
}
|
||||
|
||||
fun compute(message: ByteArray): ByteArray {
|
||||
val messageLenBytes = message.size
|
||||
val numBlocks = ((messageLenBytes + 8) ushr 6) + 1
|
||||
val totalLen = numBlocks shl 6
|
||||
val paddingBytes = ByteArray(totalLen - messageLenBytes)
|
||||
paddingBytes[0] = 0x80.toByte()
|
||||
var messageLenBits = (messageLenBytes shl 3).toLong()
|
||||
|
||||
for (i in 0..7) {
|
||||
paddingBytes[paddingBytes.size - 8 + i] = messageLenBits.toByte()
|
||||
messageLenBits = messageLenBits ushr 8
|
||||
}
|
||||
|
||||
var a = INIT_A
|
||||
var b = INIT_B
|
||||
var c = INIT_C
|
||||
var d = INIT_D
|
||||
val buffer = IntArray(16)
|
||||
|
||||
for (i in 0 until numBlocks) {
|
||||
var index = i shl 6
|
||||
|
||||
for (j in 0..63) {
|
||||
val temp = if (index < messageLenBytes) message[index] else
|
||||
paddingBytes[index - messageLenBytes]
|
||||
buffer[j ushr 2] = (temp.toInt() shl 24) or (buffer[j ushr 2] ushr 8)
|
||||
index++
|
||||
}
|
||||
|
||||
val originalA = a
|
||||
val originalB = b
|
||||
val originalC = c
|
||||
val originalD = d
|
||||
|
||||
for (j in 0..63) {
|
||||
val div16 = j ushr 4
|
||||
var f = 0
|
||||
var bufferIndex = j
|
||||
when (div16) {
|
||||
0 -> {
|
||||
f = (b and c) or (b.inv() and d)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
f = (b and d) or (c and d.inv())
|
||||
bufferIndex = (bufferIndex * 5 + 1) and 0x0F
|
||||
}
|
||||
|
||||
2 -> {
|
||||
f = b xor c xor d;
|
||||
bufferIndex = (bufferIndex * 3 + 5) and 0x0F
|
||||
}
|
||||
|
||||
3 -> {
|
||||
f = c xor (b or d.inv());
|
||||
bufferIndex = (bufferIndex * 7) and 0x0F
|
||||
}
|
||||
}
|
||||
|
||||
val temp = b + Integer.rotateLeft(a + f + buffer[bufferIndex] +
|
||||
TABLE_T[j], SHIFT_AMTS[(div16 shl 2) or (j and 3)])
|
||||
a = d
|
||||
d = c
|
||||
c = b
|
||||
b = temp
|
||||
}
|
||||
|
||||
a += originalA
|
||||
b += originalB
|
||||
c += originalC
|
||||
d += originalD
|
||||
}
|
||||
|
||||
val md5 = ByteArray(16)
|
||||
var count = 0
|
||||
|
||||
for (i in 0..3) {
|
||||
var n = if (i == 0) a else (if (i == 1) b else (if (i == 2) c else d))
|
||||
|
||||
for (j in 0..3) {
|
||||
md5[count++] = n.toByte()
|
||||
n = n ushr 8
|
||||
}
|
||||
}
|
||||
return md5
|
||||
}
|
||||
}
|
||||
|
||||
fun ByteArray.toHexString(): String {
|
||||
val sb = StringBuilder()
|
||||
for (b in this) sb.append(String.format("%02x", b.toInt() and 0xFF))
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val testStrings = arrayOf(
|
||||
"",
|
||||
"a",
|
||||
"abc",
|
||||
"message digest",
|
||||
"abcdefghijklmnopqrstuvwxyz",
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234567890"
|
||||
)
|
||||
|
||||
println("${"hash code".padStart(34)} <== string")
|
||||
for (s in testStrings) {
|
||||
println("0x${MD5.compute(s.toByteArray()).toHexString()} <== \"$s\"")
|
||||
}
|
||||
}
|
||||
181
Task/MD5-Implementation/Nim/md5-implementation.nim
Normal file
181
Task/MD5-Implementation/Nim/md5-implementation.nim
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
import sequtils
|
||||
|
||||
const
|
||||
ChunkSize = 512 div 8
|
||||
SumSize = 128 div 8
|
||||
|
||||
proc extractChunk(msg : seq[uint8], chunk: var openarray[uint32], offset: int) =
|
||||
var
|
||||
srcIndex = offset
|
||||
|
||||
for dstIndex in 0 .. < 16:
|
||||
chunk[dstIndex] = 0
|
||||
for ii in 0 .. < 4:
|
||||
chunk[dstIndex] = chunk[dstIndex] shr 8
|
||||
chunk[dstIndex] = chunk[dstIndex] or (msg[srcIndex].uint32 shl 24)
|
||||
srcIndex.inc
|
||||
|
||||
proc leftRotate(val: uint32, shift: int) : uint32 =
|
||||
result = (val shl shift) or (val shr (32 - shift))
|
||||
|
||||
proc md5Sum(msg : seq[uint8]) : array[SumSize, uint8] =
|
||||
const
|
||||
s : array[ChunkSize, int] =
|
||||
[ 7, 12, 17, 22, 7, 12, 17, 22,
|
||||
7, 12, 17, 22, 7, 12, 17, 22,
|
||||
5, 9, 14, 20, 5, 9, 14, 20,
|
||||
5, 9, 14, 20, 5, 9, 14, 20,
|
||||
4, 11, 16, 23, 4, 11, 16, 23,
|
||||
4, 11, 16, 23, 4, 11, 16, 23,
|
||||
6, 10, 15, 21, 6, 10, 15, 21,
|
||||
6, 10, 15, 21, 6, 10, 15, 21 ]
|
||||
|
||||
K : array[ChunkSize, uint32] =
|
||||
[ 0xd76aa478'u32, 0xe8c7b756'u32, 0x242070db'u32, 0xc1bdceee'u32,
|
||||
0xf57c0faf'u32, 0x4787c62a'u32, 0xa8304613'u32, 0xfd469501'u32,
|
||||
0x698098d8'u32, 0x8b44f7af'u32, 0xffff5bb1'u32, 0x895cd7be'u32,
|
||||
0x6b901122'u32, 0xfd987193'u32, 0xa679438e'u32, 0x49b40821'u32,
|
||||
0xf61e2562'u32, 0xc040b340'u32, 0x265e5a51'u32, 0xe9b6c7aa'u32,
|
||||
0xd62f105d'u32, 0x02441453'u32, 0xd8a1e681'u32, 0xe7d3fbc8'u32,
|
||||
0x21e1cde6'u32, 0xc33707d6'u32, 0xf4d50d87'u32, 0x455a14ed'u32,
|
||||
0xa9e3e905'u32, 0xfcefa3f8'u32, 0x676f02d9'u32, 0x8d2a4c8a'u32,
|
||||
0xfffa3942'u32, 0x8771f681'u32, 0x6d9d6122'u32, 0xfde5380c'u32,
|
||||
0xa4beea44'u32, 0x4bdecfa9'u32, 0xf6bb4b60'u32, 0xbebfbc70'u32,
|
||||
0x289b7ec6'u32, 0xeaa127fa'u32, 0xd4ef3085'u32, 0x04881d05'u32,
|
||||
0xd9d4d039'u32, 0xe6db99e5'u32, 0x1fa27cf8'u32, 0xc4ac5665'u32,
|
||||
0xf4292244'u32, 0x432aff97'u32, 0xab9423a7'u32, 0xfc93a039'u32,
|
||||
0x655b59c3'u32, 0x8f0ccc92'u32, 0xffeff47d'u32, 0x85845dd1'u32,
|
||||
0x6fa87e4f'u32, 0xfe2ce6e0'u32, 0xa3014314'u32, 0x4e0811a1'u32,
|
||||
0xf7537e82'u32, 0xbd3af235'u32, 0x2ad7d2bb'u32, 0xeb86d391'u32 ]
|
||||
|
||||
|
||||
# Pad with 1-bit, and fill with 0's up to 448 bits mod 512
|
||||
var paddedMsgSize = msg.len + 1
|
||||
var remain = (msg.len + 1) mod ChunkSize
|
||||
if remain > (448 div 8):
|
||||
paddedMsgSize += ChunkSize - remain + (448 div 8)
|
||||
else:
|
||||
paddedMsgSize += (448 div 8) - remain
|
||||
|
||||
var paddingSize = paddedMsgSize - msg.len
|
||||
var padding = newSeq[uint8](paddingSize)
|
||||
padding[0] = 0x80
|
||||
|
||||
# Pad with number of *bits* in original message, little-endian
|
||||
var sizePadding = newSeq[uint8](8)
|
||||
var size = msg.len * 8
|
||||
for ii in 0 .. < 4:
|
||||
sizePadding[ii] = uint8(size and 0xff)
|
||||
size = size shr 8
|
||||
|
||||
var paddedMsg = concat(msg, padding, sizePadding)
|
||||
|
||||
var accum = [ 0x67452301'u32, 0xefcdab89'u32, 0x98badcfe'u32, 0x10325476'u32 ]
|
||||
|
||||
for offset in countup(0, paddedMsg.len - 1, ChunkSize):
|
||||
var A = accum[0]
|
||||
var B = accum[1]
|
||||
var C = accum[2]
|
||||
var D = accum[3]
|
||||
var F : uint32
|
||||
var g : int
|
||||
var M : array[16, uint32]
|
||||
var dTemp : uint32
|
||||
|
||||
extractChunk(paddedMsg, M, offset)
|
||||
|
||||
# This is pretty much the same as Wikipedia's MD5 entry
|
||||
for ii in 0 .. 63:
|
||||
if ii <= 15:
|
||||
F = (B and C) or ((not B) and D)
|
||||
g = ii
|
||||
|
||||
elif ii <= 31:
|
||||
F = (D and B) or ((not D) and C)
|
||||
g = (5 * ii + 1) mod 16
|
||||
|
||||
elif ii <= 47:
|
||||
F = B xor C xor D
|
||||
g = (3 * ii + 5) mod 16
|
||||
|
||||
else:
|
||||
F = C xor (B or (not D))
|
||||
g = (7 * ii) mod 16
|
||||
|
||||
dTemp = D
|
||||
D = C
|
||||
C = B
|
||||
B = B + leftRotate((A + F + K[ii] + M[g]), s[ii])
|
||||
A = dTemp
|
||||
|
||||
accum[0] += A
|
||||
accum[1] += B
|
||||
accum[2] += C
|
||||
accum[3] += D
|
||||
|
||||
# Convert four 32-bit accumulators to 16 byte array, little-endian
|
||||
var dstIdx : int
|
||||
for acc in accum:
|
||||
var tmp = acc
|
||||
|
||||
for ii in 0 .. < 4:
|
||||
result[dstIdx] = uint8(tmp and 0xff)
|
||||
tmp = tmp shr 8
|
||||
dstIdx.inc
|
||||
|
||||
# Only needed to convert from string to uint8 sequence
|
||||
iterator items * (str : string) : uint8 =
|
||||
for ii in 0 .. < len(str):
|
||||
yield str[ii].uint8
|
||||
|
||||
proc main =
|
||||
var msg = ""
|
||||
var sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0xD4'u8, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
|
||||
0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E ] )
|
||||
|
||||
msg = "The quick brown fox jumps over the lazy dog"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0x9E'u8, 0x10, 0x7D, 0x9D, 0x37, 0x2B, 0xB6, 0x82,
|
||||
0x6B, 0xD8, 0x1D, 0x35, 0x42, 0xA4, 0x19, 0xD6 ] )
|
||||
|
||||
msg = "The quick brown fox jumps over the lazy dog."
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0xE4'u8, 0xD9, 0x09, 0xC2, 0x90, 0xD0, 0xFB, 0x1C,
|
||||
0xA0, 0x68, 0xFF, 0xAD, 0xDF, 0x22, 0xCB, 0xD0 ])
|
||||
|
||||
|
||||
# Message size around magic 512 bits
|
||||
msg = "01234567890123456789012345678901234567890123456789012345678901234"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0xBE'u8, 0xB9, 0xF4, 0x8B, 0xC8, 0x02, 0xCA, 0x5C,
|
||||
0xA0, 0x43, 0xBC, 0xC1, 0x5E, 0x21, 0x9A, 0x5A ])
|
||||
|
||||
msg = "0123456789012345678901234567890123456789012345678901234567890123"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0x7F'u8, 0x7B, 0xFD, 0x34, 0x87, 0x09, 0xDE, 0xEA,
|
||||
0xAC, 0xE1, 0x9E, 0x3F, 0x53, 0x5F, 0x8C, 0x54 ])
|
||||
|
||||
msg = "012345678901234567890123456789012345678901234567890123456789012"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0xC5'u8, 0xE2, 0x56, 0x43, 0x7E, 0x75, 0x80, 0x92,
|
||||
0xDB, 0xFE, 0x06, 0x28, 0x3E, 0x48, 0x90, 0x19 ])
|
||||
|
||||
|
||||
# Message size around magic 448 bits
|
||||
msg = "01234567890123456789012345678901234567890123456789012345"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0x8A'u8, 0xF2, 0x70, 0xB2, 0x84, 0x76, 0x10, 0xE7,
|
||||
0x42, 0xB0, 0x79, 0x1B, 0x53, 0x64, 0x8C, 0x09 ])
|
||||
|
||||
msg = "0123456789012345678901234567890123456789012345678901234"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0x6E'u8, 0x7A, 0x4F, 0xC9, 0x2E, 0xB1, 0xC3, 0xF6,
|
||||
0xE6, 0x52, 0x42, 0x5B, 0xCC, 0x8D, 0x44, 0xB5 ])
|
||||
|
||||
msg = "012345678901234567890123456789012345678901234567890123"
|
||||
sum = md5Sum(toSeq(msg.items()))
|
||||
assert(sum == [ 0x3D'u8, 0xFF, 0x83, 0xC8, 0xFA, 0xDD, 0x26, 0x37,
|
||||
0x0D, 0x5B, 0x09, 0x84, 0x09, 0x64, 0x44, 0x57 ])
|
||||
|
||||
main()
|
||||
231
Task/MD5-Implementation/OoRexx/md5-implementation.rexx
Normal file
231
Task/MD5-Implementation/OoRexx/md5-implementation.rexx
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
#!/usr/bin/rexx
|
||||
|
||||
/* Expected results:
|
||||
0xd41d8cd98f00b204e9800998ecf8427e <== ""
|
||||
0x0cc175b9c0f1b6a831c399e269772661 <== "a"
|
||||
0x900150983cd24fb0d6963f7d28e17f72 <== "abc"
|
||||
0xf96b697d7cb7938d525a2f31aaf161d0 <== "message digest"
|
||||
0xc3fcd3d76192e4007dfb496cca67e13b <== "abcdefghijklmnopqrstuvwxyz"
|
||||
0xd174ab98d277d9f5a5611c2c9f419d9f <== "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
0x57edf4a22be3c955ac49da2e2107b67a <== "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
|
||||
*/
|
||||
|
||||
md5 = .md5~new; md5~update(""); say md5~digest
|
||||
md5 = .md5~new; md5~update("a"); say md5~digest
|
||||
md5 = .md5~new; md5~update("abc"); say md5~digest
|
||||
md5 = .md5~new; md5~update("message digest"); say md5~digest
|
||||
md5 = .md5~new("abcdefghijklmnopqrstuvwxyz"); say md5~digest
|
||||
md5 = .md5~new("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); md5~update("abcdefghijklmnopqrstuvwxyz0123456789"); say md5~digest
|
||||
md5 = .md5~new; md5~update("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); say md5~digest
|
||||
|
||||
-- requires OORexx 4.2.0 or later
|
||||
-- standard numeric digits of 9 is not enough in this case
|
||||
::options digits 20
|
||||
|
||||
-- Implementation mainly based on pseudocode in https://en.wikipedia.org/wiki/MD5
|
||||
::class md5 public
|
||||
|
||||
::method init
|
||||
expose a0 b0 c0 d0 count buffer index K. s -- instance variables
|
||||
use strict arg chunk=""
|
||||
-- Initialize message digest
|
||||
a0 = .int32~new('67452301'x,"C") -- A
|
||||
b0 = .int32~new('efcdab89'x,"C") -- B
|
||||
c0 = .int32~new('98badcfe'x,"C") -- C
|
||||
d0 = .int32~new('10325476'x,"C") -- D
|
||||
-- The 512 bit chunk buffer
|
||||
buffer = .mutablebuffer~new('00'x~copies(64),64)
|
||||
-- The position in the buffer to insert new input
|
||||
index = 1
|
||||
-- message bytecount
|
||||
count = 0
|
||||
-- initialize leftrotate amounts
|
||||
nrs = .array~of(7,12,17,22)
|
||||
s = nrs~union(nrs)~union(nrs)~union(nrs)
|
||||
nrs = .array~of(5,9,14,20)
|
||||
s = s~union(nrs)~union(nrs)~union(nrs)~union(nrs)
|
||||
nrs = .array~of(4,11,16,23)
|
||||
s = s~union(nrs)~union(nrs)~union(nrs)~union(nrs)
|
||||
nrs = .array~of(6,10,15,21)
|
||||
s = s~union(nrs)~union(nrs)~union(nrs)~union(nrs)
|
||||
-- initialize sinus derived constants.
|
||||
-- sin function from RXMath Library shipped with OORexx
|
||||
-- see ::routine directive at the end of the code
|
||||
do i=0 to 63
|
||||
K.i = .int32~new(((2**32)*(sin(i+1,16,R)~abs))~floor)
|
||||
end
|
||||
-- process initial string if any
|
||||
self~update(chunk)
|
||||
exit
|
||||
|
||||
::method update
|
||||
expose a0 b0 c0 d0 count buffer index K. s -- instance variables
|
||||
use strict arg chunk
|
||||
count += chunk~length
|
||||
if chunk~length<65-index then do
|
||||
buffer~overlay(chunk,index)
|
||||
index += chunk~length
|
||||
end
|
||||
else do
|
||||
split = 65-index+1
|
||||
parse var chunk part =(split) chunk
|
||||
buffer~overlay(part,index)
|
||||
index = 65
|
||||
end
|
||||
-- Only proces completely filled buffer
|
||||
do while index=65
|
||||
A = a0
|
||||
B = b0
|
||||
C = c0
|
||||
D = d0
|
||||
do i=0 to 63
|
||||
select
|
||||
when i<16 then do
|
||||
F = D~xor(B~and(C~xor(D)))
|
||||
g = i
|
||||
end
|
||||
when i<32 then do
|
||||
F = C~xor(D~and(B~xor(C)))
|
||||
g = (5*i+1)//16
|
||||
end
|
||||
when i<48 then do
|
||||
F = B~xor(C)~xor(D)
|
||||
g = (3*i+5)//16
|
||||
end
|
||||
otherwise do
|
||||
F = C~xor(B~or(D~xor(.int32~new('ffffffff'x,"C"))))
|
||||
g = (7*i)//16
|
||||
end
|
||||
end
|
||||
M = .int32~new(buffer~substr(g*4+1,4)~reverse,"C") -- 32bit word in little-endian
|
||||
dTemp = D
|
||||
D = C
|
||||
C = B
|
||||
B = (B + (A+F+K.i+M)~bitrotate(s[i+1]))
|
||||
A = dTemp
|
||||
end
|
||||
a0 = a0+A
|
||||
b0 = b0+B
|
||||
c0 = c0+C
|
||||
d0 = d0+D
|
||||
parse var chunk part 65 chunk
|
||||
index = part~length+1
|
||||
buffer~overlay(part,1,part~length)
|
||||
end
|
||||
exit
|
||||
|
||||
::method digest
|
||||
expose a0 b0 c0 d0 count buffer index K s -- instance variables
|
||||
padlen = 64
|
||||
if index<57 then padlen = 57-index
|
||||
if index>57 then padlen = 121-index
|
||||
padding = '00'x~copies(padlen)~bitor('80'x)
|
||||
bitcount = count*8//2**64
|
||||
lowword = bitcount//2**32
|
||||
hiword = bitcount%2**32
|
||||
lowcount = lowword~d2c(4)~reverse -- make it little-endian
|
||||
hicount = hiword~d2c(4)~reverse -- make it little-endian
|
||||
self~update(padding || lowcount || hicount)
|
||||
return a0~string || b0~string || c0~string || d0~string
|
||||
|
||||
-- A convenience class to encapsulate operations on non OORexx-like
|
||||
-- things as little-endian 32-bit words
|
||||
::class int32 public
|
||||
|
||||
::attribute arch class
|
||||
|
||||
::method init class
|
||||
self~arch = "little-endian" -- can be adapted for multiple architectures
|
||||
|
||||
-- Method to create an int32 like object
|
||||
-- Input can be a OORexx whole number (type="I") or
|
||||
-- a character string of 4 bytes (type="C")
|
||||
-- input truncated or padded to 32-bit word/string
|
||||
::method init
|
||||
expose char4 int32
|
||||
use strict arg input, type="Integer"
|
||||
-- type must be one of "I"nteger or "C"haracter
|
||||
t = type~subchar(1)~upper
|
||||
select
|
||||
when t=='I' then do
|
||||
char4 = input~d2c(4)
|
||||
int32 = char4~c2d
|
||||
end
|
||||
when t=='C' then do
|
||||
char4 = input~right(4,'00'x)
|
||||
int32 = char4~c2d
|
||||
end
|
||||
otherwise do
|
||||
raise syntax 93.915 array("IC",type)
|
||||
end
|
||||
end
|
||||
exit
|
||||
|
||||
::method xor -- wrapper for OORexx bitxor method
|
||||
expose char4
|
||||
use strict arg other
|
||||
return .int32~new(char4~bitxor(other~char),"C")
|
||||
|
||||
::method and -- wrapper for OORexx bitand method
|
||||
expose char4
|
||||
use strict arg other
|
||||
return .int32~new(char4~bitand(other~char),"C")
|
||||
|
||||
::method or -- wrapper for OORexx bitor method
|
||||
expose char4
|
||||
use strict arg other
|
||||
return .int32~new(char4~bitor(other~char),"C")
|
||||
|
||||
::method bitleft -- OORexx shift (<<) implementation
|
||||
expose char4
|
||||
use strict arg bits
|
||||
bstring = char4~c2x~x2b
|
||||
bstring = bstring~substr(bits+1)~left(bstring~length,'0')
|
||||
return .int32~new(bstring~b2x~x2d)
|
||||
|
||||
::method bitright -- OORexx shift (>>) implementation
|
||||
expose char4
|
||||
use strict arg bits, signed=.false
|
||||
bstring = char4~c2x~x2b
|
||||
fill = '0'
|
||||
if signed then fill = bstring~subchar(1)
|
||||
bstring = bstring~left(bstring~length-bits)~right(bstring~length,fill)
|
||||
return .int32~new(bstring~b2x~x2d)
|
||||
|
||||
::method bitnot -- OORexx not implementation
|
||||
expose char4
|
||||
return .int32~new(char4~bitxor('ffffffff'x)~c2d,"C")
|
||||
|
||||
::method bitrotate -- OORexx (left) rotate method
|
||||
expose char4
|
||||
use strict arg bits, direction='left'
|
||||
d = direction~subchar(1)~upper
|
||||
if d=='L' then do
|
||||
leftpart = self~bitleft(bits)
|
||||
rightpart = self~bitright(32-bits)
|
||||
end
|
||||
else do
|
||||
leftpart = self~bitleft(32-bits)
|
||||
rightpart = self~bitright(bits)
|
||||
end
|
||||
return rightpart~or(leftpart)
|
||||
|
||||
::method int -- retrieve integer as number
|
||||
expose int32
|
||||
return int32
|
||||
|
||||
::method char -- retrieve integer as characters
|
||||
expose char4
|
||||
return char4
|
||||
|
||||
::method '+' -- OORexx method to add 2 .int32 instances
|
||||
expose int32
|
||||
use strict arg other
|
||||
return .int32~new(int32+other~int)
|
||||
|
||||
::method string -- retrieve integer as hexadecimal string
|
||||
expose char4
|
||||
return char4~reverse~c2x~lower
|
||||
|
||||
-- Simplify function names for the necessary 'RxMath' functions
|
||||
::routine sin EXTERNAL "LIBRARY rxmath RxCalcSin"
|
||||
|
|
@ -1,115 +1,114 @@
|
|||
/*REXX program tests the MD5 procedure (below) as per a test suite the IETF RFC (1321).*/
|
||||
msg.1 = /*─────MD5 test suite [from above doc].*/
|
||||
msg.2 = 'a'
|
||||
msg.3 = 'abc'
|
||||
msg.4 = 'message digest'
|
||||
msg.5 = 'abcdefghijklmnopqrstuvwxyz'
|
||||
msg.6 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
msg.7 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
msg.0 = 7 /* [↑] last value doesn't need quotes.*/
|
||||
do m=1 for msg.0; say /*process each of the seven messages. */
|
||||
say ' in =' msg.m /*display the in message. */
|
||||
say 'out =' MD5(msg.m) /* " " out " */
|
||||
/*REXX program tests the MD5 procedure (below) as per a test suite from IETF RFC (1321).*/
|
||||
@.1 = /*─────MD5 test suite [from above doc].*/
|
||||
@.2 = 'a'
|
||||
@.3 = 'abc'
|
||||
@.4 = 'message digest'
|
||||
@.5 = 'abcdefghijklmnopqrstuvwxyz'
|
||||
@.6 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
@.7 = 12345678901234567890123456789012345678901234567890123456789012345678901234567890
|
||||
@.0 = 7 /* [↑] last value doesn't need quotes.*/
|
||||
do m=1 for @.0; say /*process each of the seven messages. */
|
||||
say ' in =' @.m /*display the in message. */
|
||||
say 'out =' MD5(@.m) /* " " out " */
|
||||
end /*m*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
MD5: procedure; parse arg !; numeric digits 20 /*insure there's enough decimal digits.*/
|
||||
a='67452301'x; b="efcdab89"x; c='98badcfe'x; d="10325476"x; x00='0'x; x80="80"x
|
||||
a= '67452301'x; b= "efcdab89"x; c= '98badcfe'x; d= "10325476"x
|
||||
#=length(!) /*length in bytes of the input message.*/
|
||||
L=#*8//512; if L<448 then plus=448-L /*is the length less than 448 ? */
|
||||
if L>448 then plus=960-L /* " " " greater " " */
|
||||
if L=448 then plus=512 /* " " " equal to " */
|
||||
x00000000='00000000'x /* [↓] a little of this, ··· */
|
||||
$=! || x80 || copies( x00, plus%8 -1 )reverse(right(d2c(8 * #), 4, x00)) || x00000000
|
||||
L=# *8 //512; if L<448 then plus=448 - L /*is the length less than 448 ? */
|
||||
if L>448 then plus=960 - L /* " " " greater " " */
|
||||
if L=448 then plus=512 /* " " " equal to " */
|
||||
/* [↓] a little of this, ··· */
|
||||
$=! || "80"x || copies('0'x,plus%8-1)reverse(right(d2c(8*#), 4, '0'x)) || '00000000'x
|
||||
/* [↑] ··· and a little of that.*/
|
||||
do j=0 to length($)%64-1 /*process the message (lots of steps).*/
|
||||
a_=a; b_=b; c_=c; d_=d /*save the original values for later.*/
|
||||
chunk=j*64 /*calculate the size of the chunks. */
|
||||
do k=1 for 16 /*process the message in chunks. */
|
||||
!.k=reverse( substr($, chunk + 1 + 4*(k-1), 4) ) /*magic stuff.*/
|
||||
end /*k*/
|
||||
|
||||
a = .part1( a, b, c, d, 0, 7, 3614090360) /*■■■■ 1 ■■■■*/
|
||||
d = .part1( d, a, b, c, 1, 12, 3905402710) /*■■■■ 2 ■■■■*/
|
||||
c = .part1( c, d, a, b, 2, 17, 606105819) /*■■■■ 3 ■■■■*/
|
||||
b = .part1( b, c, d, a, 3, 22, 3250441966) /*■■■■ 4 ■■■■*/
|
||||
a = .part1( a, b, c, d, 4, 7, 4118548399) /*■■■■ 5 ■■■■*/
|
||||
d = .part1( d, a, b, c, 5, 12, 1200080426) /*■■■■ 6 ■■■■*/
|
||||
c = .part1( c, d, a, b, 6, 17, 2821735955) /*■■■■ 7 ■■■■*/
|
||||
b = .part1( b, c, d, a, 7, 22, 4249261313) /*■■■■ 8 ■■■■*/
|
||||
a = .part1( a, b, c, d, 8, 7, 1770035416) /*■■■■ 9 ■■■■*/
|
||||
d = .part1( d, a, b, c, 9, 12, 2336552879) /*■■■■ 10 ■■■■*/
|
||||
c = .part1( c, d, a, b, 10, 17, 4294925233) /*■■■■ 11 ■■■■*/
|
||||
b = .part1( b, c, d, a, 11, 22, 2304563134) /*■■■■ 12 ■■■■*/
|
||||
a = .part1( a, b, c, d, 12, 7, 1804603682) /*■■■■ 13 ■■■■*/
|
||||
d = .part1( d, a, b, c, 13, 12, 4254626195) /*■■■■ 14 ■■■■*/
|
||||
c = .part1( c, d, a, b, 14, 17, 2792965006) /*■■■■ 15 ■■■■*/
|
||||
b = .part1( b, c, d, a, 15, 22, 1236535329) /*■■■■ 16 ■■■■*/
|
||||
a = .part2( a, b, c, d, 1, 5, 4129170786) /*■■■■ 17 ■■■■*/
|
||||
d = .part2( d, a, b, c, 6, 9, 3225465664) /*■■■■ 18 ■■■■*/
|
||||
c = .part2( c, d, a, b, 11, 14, 643717713) /*■■■■ 19 ■■■■*/
|
||||
b = .part2( b, c, d, a, 0, 20, 3921069994) /*■■■■ 20 ■■■■*/
|
||||
a = .part2( a, b, c, d, 5, 5, 3593408605) /*■■■■ 21 ■■■■*/
|
||||
d = .part2( d, a, b, c, 10, 9, 38016083) /*■■■■ 22 ■■■■*/
|
||||
c = .part2( c, d, a, b, 15, 14, 3634488961) /*■■■■ 23 ■■■■*/
|
||||
b = .part2( b, c, d, a, 4, 20, 3889429448) /*■■■■ 24 ■■■■*/
|
||||
a = .part2( a, b, c, d, 9, 5, 568446438) /*■■■■ 25 ■■■■*/
|
||||
d = .part2( d, a, b, c, 14, 9, 3275163606) /*■■■■ 26 ■■■■*/
|
||||
c = .part2( c, d, a, b, 3, 14, 4107603335) /*■■■■ 27 ■■■■*/
|
||||
b = .part2( b, c, d, a, 8, 20, 1163531501) /*■■■■ 28 ■■■■*/
|
||||
a = .part2( a, b, c, d, 13, 5, 2850285829) /*■■■■ 29 ■■■■*/
|
||||
d = .part2( d, a, b, c, 2, 9, 4243563512) /*■■■■ 30 ■■■■*/
|
||||
c = .part2( c, d, a, b, 7, 14, 1735328473) /*■■■■ 31 ■■■■*/
|
||||
b = .part2( b, c, d, a, 12, 20, 2368359562) /*■■■■ 32 ■■■■*/
|
||||
a = .part3( a, b, c, d, 5, 4, 4294588738) /*■■■■ 33 ■■■■*/
|
||||
d = .part3( d, a, b, c, 8, 11, 2272392833) /*■■■■ 34 ■■■■*/
|
||||
c = .part3( c, d, a, b, 11, 16, 1839030562) /*■■■■ 35 ■■■■*/
|
||||
b = .part3( b, c, d, a, 14, 23, 4259657740) /*■■■■ 36 ■■■■*/
|
||||
a = .part3( a, b, c, d, 1, 4, 2763975236) /*■■■■ 37 ■■■■*/
|
||||
d = .part3( d, a, b, c, 4, 11, 1272893353) /*■■■■ 38 ■■■■*/
|
||||
c = .part3( c, d, a, b, 7, 16, 4139469664) /*■■■■ 39 ■■■■*/
|
||||
b = .part3( b, c, d, a, 10, 23, 3200236656) /*■■■■ 40 ■■■■*/
|
||||
a = .part3( a, b, c, d, 13, 4, 681279174) /*■■■■ 41 ■■■■*/
|
||||
d = .part3( d, a, b, c, 0, 11, 3936430074) /*■■■■ 42 ■■■■*/
|
||||
c = .part3( c, d, a, b, 3, 16, 3572445317) /*■■■■ 43 ■■■■*/
|
||||
b = .part3( b, c, d, a, 6, 23, 76029189) /*■■■■ 44 ■■■■*/
|
||||
a = .part3( a, b, c, d, 9, 4, 3654602809) /*■■■■ 45 ■■■■*/
|
||||
d = .part3( d, a, b, c, 12, 11, 3873151461) /*■■■■ 46 ■■■■*/
|
||||
c = .part3( c, d, a, b, 15, 16, 530742520) /*■■■■ 47 ■■■■*/
|
||||
b = .part3( b, c, d, a, 2, 23, 3299628645) /*■■■■ 48 ■■■■*/
|
||||
a = .part4( a, b, c, d, 0, 6, 4096336452) /*■■■■ 49 ■■■■*/
|
||||
d = .part4( d, a, b, c, 7, 10, 1126891415) /*■■■■ 50 ■■■■*/
|
||||
c = .part4( c, d, a, b, 14, 15, 2878612391) /*■■■■ 51 ■■■■*/
|
||||
b = .part4( b, c, d, a, 5, 21, 4237533241) /*■■■■ 52 ■■■■*/
|
||||
a = .part4( a, b, c, d, 12, 6, 1700485571) /*■■■■ 53 ■■■■*/
|
||||
d = .part4( d, a, b, c, 3, 10, 2399980690) /*■■■■ 54 ■■■■*/
|
||||
c = .part4( c, d, a, b, 10, 15, 4293915773) /*■■■■ 55 ■■■■*/
|
||||
b = .part4( b, c, d, a, 1, 21, 2240044497) /*■■■■ 56 ■■■■*/
|
||||
a = .part4( a, b, c, d, 8, 6, 1873313359) /*■■■■ 57 ■■■■*/
|
||||
d = .part4( d, a, b, c, 15, 10, 4264355552) /*■■■■ 58 ■■■■*/
|
||||
c = .part4( c, d, a, b, 6, 15, 2734768916) /*■■■■ 59 ■■■■*/
|
||||
b = .part4( b, c, d, a, 13, 21, 1309151649) /*■■■■ 60 ■■■■*/
|
||||
a = .part4( a, b, c, d, 4, 6, 4149444226) /*■■■■ 61 ■■■■*/
|
||||
d = .part4( d, a, b, c, 11, 10, 3174756917) /*■■■■ 62 ■■■■*/
|
||||
c = .part4( c, d, a, b, 2, 15, 718787259) /*■■■■ 63 ■■■■*/
|
||||
b = .part4( b, c, d, a, 9, 21, 3951481745) /*■■■■ 64 ■■■■*/
|
||||
a = .a(a_,a); b=.a(b_,b); c=.a(c_,c); d=.a(d_,d)
|
||||
end /*j*/
|
||||
|
||||
return c2x( reverse(a) )c2x( reverse(b) )c2x( reverse(c) )c2x( reverse(d) )
|
||||
do j=0 for length($) % 64 /*process the message (lots of steps).*/
|
||||
a_=a; b_=b; c_=c; d_=d /*save the original values for later.*/
|
||||
chunk=j * 64 /*calculate the size of the chunks. */
|
||||
do k=1 for 16 /*process the message in chunks. */
|
||||
!.k=reverse( substr($, chunk + 1 + 4*(k-1), 4) ) /*magic stuff.*/
|
||||
end /*k*/ /*────step────*/
|
||||
a = .p1( a, b, c, d, 0, 7, 3614090360) /*■■■■ 1 ■■■■*/
|
||||
d = .p1( d, a, b, c, 1, 12, 3905402710) /*■■■■ 2 ■■■■*/
|
||||
c = .p1( c, d, a, b, 2, 17, 606105819) /*■■■■ 3 ■■■■*/
|
||||
b = .p1( b, c, d, a, 3, 22, 3250441966) /*■■■■ 4 ■■■■*/
|
||||
a = .p1( a, b, c, d, 4, 7, 4118548399) /*■■■■ 5 ■■■■*/
|
||||
d = .p1( d, a, b, c, 5, 12, 1200080426) /*■■■■ 6 ■■■■*/
|
||||
c = .p1( c, d, a, b, 6, 17, 2821735955) /*■■■■ 7 ■■■■*/
|
||||
b = .p1( b, c, d, a, 7, 22, 4249261313) /*■■■■ 8 ■■■■*/
|
||||
a = .p1( a, b, c, d, 8, 7, 1770035416) /*■■■■ 9 ■■■■*/
|
||||
d = .p1( d, a, b, c, 9, 12, 2336552879) /*■■■■ 10 ■■■■*/
|
||||
c = .p1( c, d, a, b, 10, 17, 4294925233) /*■■■■ 11 ■■■■*/
|
||||
b = .p1( b, c, d, a, 11, 22, 2304563134) /*■■■■ 12 ■■■■*/
|
||||
a = .p1( a, b, c, d, 12, 7, 1804603682) /*■■■■ 13 ■■■■*/
|
||||
d = .p1( d, a, b, c, 13, 12, 4254626195) /*■■■■ 14 ■■■■*/
|
||||
c = .p1( c, d, a, b, 14, 17, 2792965006) /*■■■■ 15 ■■■■*/
|
||||
b = .p1( b, c, d, a, 15, 22, 1236535329) /*■■■■ 16 ■■■■*/
|
||||
a = .p2( a, b, c, d, 1, 5, 4129170786) /*■■■■ 17 ■■■■*/
|
||||
d = .p2( d, a, b, c, 6, 9, 3225465664) /*■■■■ 18 ■■■■*/
|
||||
c = .p2( c, d, a, b, 11, 14, 643717713) /*■■■■ 19 ■■■■*/
|
||||
b = .p2( b, c, d, a, 0, 20, 3921069994) /*■■■■ 20 ■■■■*/
|
||||
a = .p2( a, b, c, d, 5, 5, 3593408605) /*■■■■ 21 ■■■■*/
|
||||
d = .p2( d, a, b, c, 10, 9, 38016083) /*■■■■ 22 ■■■■*/
|
||||
c = .p2( c, d, a, b, 15, 14, 3634488961) /*■■■■ 23 ■■■■*/
|
||||
b = .p2( b, c, d, a, 4, 20, 3889429448) /*■■■■ 24 ■■■■*/
|
||||
a = .p2( a, b, c, d, 9, 5, 568446438) /*■■■■ 25 ■■■■*/
|
||||
d = .p2( d, a, b, c, 14, 9, 3275163606) /*■■■■ 26 ■■■■*/
|
||||
c = .p2( c, d, a, b, 3, 14, 4107603335) /*■■■■ 27 ■■■■*/
|
||||
b = .p2( b, c, d, a, 8, 20, 1163531501) /*■■■■ 28 ■■■■*/
|
||||
a = .p2( a, b, c, d, 13, 5, 2850285829) /*■■■■ 29 ■■■■*/
|
||||
d = .p2( d, a, b, c, 2, 9, 4243563512) /*■■■■ 30 ■■■■*/
|
||||
c = .p2( c, d, a, b, 7, 14, 1735328473) /*■■■■ 31 ■■■■*/
|
||||
b = .p2( b, c, d, a, 12, 20, 2368359562) /*■■■■ 32 ■■■■*/
|
||||
a = .p3( a, b, c, d, 5, 4, 4294588738) /*■■■■ 33 ■■■■*/
|
||||
d = .p3( d, a, b, c, 8, 11, 2272392833) /*■■■■ 34 ■■■■*/
|
||||
c = .p3( c, d, a, b, 11, 16, 1839030562) /*■■■■ 35 ■■■■*/
|
||||
b = .p3( b, c, d, a, 14, 23, 4259657740) /*■■■■ 36 ■■■■*/
|
||||
a = .p3( a, b, c, d, 1, 4, 2763975236) /*■■■■ 37 ■■■■*/
|
||||
d = .p3( d, a, b, c, 4, 11, 1272893353) /*■■■■ 38 ■■■■*/
|
||||
c = .p3( c, d, a, b, 7, 16, 4139469664) /*■■■■ 39 ■■■■*/
|
||||
b = .p3( b, c, d, a, 10, 23, 3200236656) /*■■■■ 40 ■■■■*/
|
||||
a = .p3( a, b, c, d, 13, 4, 681279174) /*■■■■ 41 ■■■■*/
|
||||
d = .p3( d, a, b, c, 0, 11, 3936430074) /*■■■■ 42 ■■■■*/
|
||||
c = .p3( c, d, a, b, 3, 16, 3572445317) /*■■■■ 43 ■■■■*/
|
||||
b = .p3( b, c, d, a, 6, 23, 76029189) /*■■■■ 44 ■■■■*/
|
||||
a = .p3( a, b, c, d, 9, 4, 3654602809) /*■■■■ 45 ■■■■*/
|
||||
d = .p3( d, a, b, c, 12, 11, 3873151461) /*■■■■ 46 ■■■■*/
|
||||
c = .p3( c, d, a, b, 15, 16, 530742520) /*■■■■ 47 ■■■■*/
|
||||
b = .p3( b, c, d, a, 2, 23, 3299628645) /*■■■■ 48 ■■■■*/
|
||||
a = .p4( a, b, c, d, 0, 6, 4096336452) /*■■■■ 49 ■■■■*/
|
||||
d = .p4( d, a, b, c, 7, 10, 1126891415) /*■■■■ 50 ■■■■*/
|
||||
c = .p4( c, d, a, b, 14, 15, 2878612391) /*■■■■ 51 ■■■■*/
|
||||
b = .p4( b, c, d, a, 5, 21, 4237533241) /*■■■■ 52 ■■■■*/
|
||||
a = .p4( a, b, c, d, 12, 6, 1700485571) /*■■■■ 53 ■■■■*/
|
||||
d = .p4( d, a, b, c, 3, 10, 2399980690) /*■■■■ 54 ■■■■*/
|
||||
c = .p4( c, d, a, b, 10, 15, 4293915773) /*■■■■ 55 ■■■■*/
|
||||
b = .p4( b, c, d, a, 1, 21, 2240044497) /*■■■■ 56 ■■■■*/
|
||||
a = .p4( a, b, c, d, 8, 6, 1873313359) /*■■■■ 57 ■■■■*/
|
||||
d = .p4( d, a, b, c, 15, 10, 4264355552) /*■■■■ 58 ■■■■*/
|
||||
c = .p4( c, d, a, b, 6, 15, 2734768916) /*■■■■ 59 ■■■■*/
|
||||
b = .p4( b, c, d, a, 13, 21, 1309151649) /*■■■■ 60 ■■■■*/
|
||||
a = .p4( a, b, c, d, 4, 6, 4149444226) /*■■■■ 61 ■■■■*/
|
||||
d = .p4( d, a, b, c, 11, 10, 3174756917) /*■■■■ 62 ■■■■*/
|
||||
c = .p4( c, d, a, b, 2, 15, 718787259) /*■■■■ 63 ■■■■*/
|
||||
b = .p4( b, c, d, a, 9, 21, 3951481745) /*■■■■ 64 ■■■■*/
|
||||
a = .a(a_, a); b=.a(b_, b); c=.a(c_, c); d=.a(d_, d)
|
||||
end /*j*/
|
||||
return .rx(a).rx(b).rx(c).rx(d) /*same as: .rx(a) || .rx(b) || ··· */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
.a: return right(d2c(c2d(arg(1)) + c2d(arg(2))), 4, '0'x)
|
||||
.h: return bitxor(bitxor(arg(1), arg(2)), arg(3))
|
||||
.i: return bitxor(arg(2), bitor(arg(1), bitxor(arg(3), 'ffffffff'x)))
|
||||
.f: return bitor(bitand(arg(1),arg(2)), bitand(bitxor(arg(1), 'ffffffff'x), arg(3)))
|
||||
.g: return bitor(bitand(arg(1),arg(3)), bitand(arg(2), bitxor(arg(3), 'ffffffff'x)))
|
||||
.Lr: procedure; parse arg _,#; if #==0 then return _ /*left rotate.*/
|
||||
?=x2b(c2x(_)); return x2c(b2x(right(? || left(?, #), length(?))))
|
||||
.part1: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.f(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part2: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.g(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part3: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(_+c2d(w)+c2d(.h(x,y,z))+c2d(!.n)),4,'0'x),m),x)
|
||||
.part4: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n+1
|
||||
return .a(.Lr(right(d2c(c2d(w)+c2d(.i(x,y,z))+c2d(!.n)+_),4,'0'x),m),x)
|
||||
.a: return right( d2c( c2d( arg(1) ) + c2d( arg(2) ) ), 4, '0'x)
|
||||
.h: return bitxor( bitxor( arg(1), arg(2) ), arg(3) )
|
||||
.i: return bitxor( arg(2), bitor(arg(1), bitxor(arg(3), 'ffffffff'x) ) )
|
||||
.f: return bitor( bitand(arg(1), arg(2)), bitand(bitxor(arg(1), 'ffffffff'x), arg(3) ) )
|
||||
.g: return bitor( bitand(arg(1), arg(3)), bitand(arg(2), bitxor(arg(3), 'ffffffff'x) ) )
|
||||
.rx: return c2x( reverse( arg(1) ) )
|
||||
.Lr: procedure; parse arg _,#; if #==0 then return _ /*left bit rotate.*/
|
||||
?=x2b(c2x(_)); return x2c( b2x( right(? || left(?, #), length(?) ) ) )
|
||||
.p1: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n + 1
|
||||
return .a(.Lr(right(d2c(_+c2d(w) + c2d(.f(x,y,z)) + c2d(!.n)),4,'0'x),m),x)
|
||||
.p2: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n + 1
|
||||
return .a(.Lr(right(d2c(_+c2d(w) + c2d(.g(x,y,z)) + c2d(!.n)),4,'0'x),m),x)
|
||||
.p3: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n + 1
|
||||
return .a(.Lr(right(d2c(_+c2d(w) + c2d(.h(x,y,z)) + c2d(!.n)),4,'0'x),m),x)
|
||||
.p4: procedure expose !.; parse arg w,x,y,z,n,m,_; n=n + 1
|
||||
return .a(.Lr(right(d2c(c2d(w) + c2d(.i(x,y,z)) + c2d(!.n)+_),4,'0'x),m),x)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class MD5(String msg) {
|
|||
[6, 10, 15, 21] * 4,
|
||||
].flat
|
||||
|
||||
const T = 64.of {|i| floor(abs(sin(i)) * 1<<32) }
|
||||
const T = 64.of {|i| floor(abs(sin(i+1)) * 1<<32) }
|
||||
|
||||
const K = [
|
||||
^16 -> map {|n| n },
|
||||
|
|
@ -45,7 +45,7 @@ class MD5(String msg) {
|
|||
var padded = [msg..., 128, [0] * (-(floor(bits / 8) + 1 + 8) % 64)].flat
|
||||
|
||||
gather {
|
||||
padded.each_slice(4, {|a|
|
||||
padded.each_slice(4, {|*a|
|
||||
take(radix(256, a))
|
||||
})
|
||||
take(little_endian(32, 2, [bits]))
|
||||
|
|
@ -66,7 +66,7 @@ class MD5(String msg) {
|
|||
), B, C)
|
||||
}
|
||||
|
||||
for k,v in ([A, B, C, D].pairs) {
|
||||
for k,v in ([A, B, C, D].kv) {
|
||||
H[k] = block(H[k], v)
|
||||
}
|
||||
|
||||
|
|
|
|||
267
Task/MD5-Implementation/X86-Assembly/md5-implementation.x86
Normal file
267
Task/MD5-Implementation/X86-Assembly/md5-implementation.x86
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
section .text
|
||||
org 0x100
|
||||
mov di, md5_for_display
|
||||
mov si, test_input_1
|
||||
mov cx, test_input_1_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov si, test_input_2
|
||||
mov cx, test_input_2_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov si, test_input_3
|
||||
mov cx, test_input_3_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov si, test_input_4
|
||||
mov cx, test_input_4_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov si, test_input_5
|
||||
mov cx, test_input_5_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov si, test_input_6
|
||||
mov cx, test_input_6_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov si, test_input_7
|
||||
mov cx, test_input_7_len
|
||||
call compute_md5
|
||||
call display_md5
|
||||
mov ax, 0x4c00
|
||||
int 21h
|
||||
|
||||
md5_for_display times 16 db 0
|
||||
HEX_CHARS db '0123456789ABCDEF'
|
||||
|
||||
display_md5:
|
||||
mov ah, 9
|
||||
mov dx, display_str_1
|
||||
int 0x21
|
||||
push cx
|
||||
push si
|
||||
mov cx, 16
|
||||
mov si, di
|
||||
xor bx, bx
|
||||
.loop:
|
||||
lodsb
|
||||
mov bl, al
|
||||
and bl, 0x0F
|
||||
push bx
|
||||
mov bl, al
|
||||
shr bx, 4
|
||||
mov ah, 2
|
||||
mov dl, [HEX_CHARS + bx]
|
||||
int 0x21
|
||||
pop bx
|
||||
mov dl, [HEX_CHARS + bx]
|
||||
int 0x21
|
||||
dec cx
|
||||
jnz .loop
|
||||
mov ah, 9
|
||||
mov dx, display_str_2
|
||||
int 0x21
|
||||
pop si
|
||||
pop cx
|
||||
test cx, cx
|
||||
jz do_newline
|
||||
mov ah, 2
|
||||
display_string:
|
||||
lodsb
|
||||
mov dl, al
|
||||
int 0x21
|
||||
dec cx
|
||||
jnz display_string
|
||||
do_newline:
|
||||
mov ah, 9
|
||||
mov dx, display_str_3
|
||||
int 0x21
|
||||
ret;
|
||||
|
||||
compute_md5:
|
||||
; si --> input bytes, cx = input len, di --> 16-byte output buffer
|
||||
; assumes all in the same segment
|
||||
cld
|
||||
pusha
|
||||
push di
|
||||
push si
|
||||
mov [message_len], cx
|
||||
|
||||
mov bx, cx
|
||||
shr bx, 6
|
||||
mov [ending_bytes_block_num], bx
|
||||
mov [num_blocks], bx
|
||||
inc word [num_blocks]
|
||||
shl bx, 6
|
||||
add si, bx
|
||||
and cx, 0x3f
|
||||
push cx
|
||||
mov di, ending_bytes
|
||||
rep movsb
|
||||
mov al, 0x80
|
||||
stosb
|
||||
pop cx
|
||||
sub cx, 55
|
||||
neg cx
|
||||
jge add_padding
|
||||
add cx, 64
|
||||
inc word [num_blocks]
|
||||
add_padding:
|
||||
mov al, 0
|
||||
rep stosb
|
||||
xor eax, eax
|
||||
mov ax, [message_len]
|
||||
shl eax, 3
|
||||
mov cx, 8
|
||||
store_message_len:
|
||||
stosb
|
||||
shr eax, 8
|
||||
dec cx
|
||||
jnz store_message_len
|
||||
pop si
|
||||
mov [md5_a], dword INIT_A
|
||||
mov [md5_b], dword INIT_B
|
||||
mov [md5_c], dword INIT_C
|
||||
mov [md5_d], dword INIT_D
|
||||
block_loop:
|
||||
push cx
|
||||
cmp cx, [ending_bytes_block_num]
|
||||
jne backup_abcd
|
||||
; switch buffers if towards the end where padding needed
|
||||
mov si, ending_bytes
|
||||
backup_abcd:
|
||||
push dword [md5_d]
|
||||
push dword [md5_c]
|
||||
push dword [md5_b]
|
||||
push dword [md5_a]
|
||||
xor cx, cx
|
||||
xor eax, eax
|
||||
main_loop:
|
||||
push cx
|
||||
mov ax, cx
|
||||
shr ax, 4
|
||||
test al, al
|
||||
jz pass0
|
||||
cmp al, 1
|
||||
je pass1
|
||||
cmp al, 2
|
||||
je pass2
|
||||
; pass3
|
||||
mov eax, [md5_c]
|
||||
mov ebx, [md5_d]
|
||||
not ebx
|
||||
or ebx, [md5_b]
|
||||
xor eax, ebx
|
||||
jmp do_rotate
|
||||
|
||||
pass0:
|
||||
mov eax, [md5_b]
|
||||
mov ebx, eax
|
||||
and eax, [md5_c]
|
||||
not ebx
|
||||
and ebx, [md5_d]
|
||||
or eax, ebx
|
||||
jmp do_rotate
|
||||
|
||||
pass1:
|
||||
mov eax, [md5_d]
|
||||
mov edx, eax
|
||||
and eax, [md5_b]
|
||||
not edx
|
||||
and edx, [md5_c]
|
||||
or eax, edx
|
||||
jmp do_rotate
|
||||
|
||||
pass2:
|
||||
mov eax, [md5_b]
|
||||
xor eax, [md5_c]
|
||||
xor eax, [md5_d]
|
||||
do_rotate:
|
||||
add eax, [md5_a]
|
||||
mov bx, cx
|
||||
shl bx, 1
|
||||
mov bx, [BUFFER_INDEX_TABLE + bx]
|
||||
add eax, [si + bx]
|
||||
mov bx, cx
|
||||
shl bx, 2
|
||||
add eax, dword [TABLE_T + bx]
|
||||
mov bx, cx
|
||||
ror bx, 2
|
||||
shr bl, 2
|
||||
rol bx, 2
|
||||
mov cl, [SHIFT_AMTS + bx]
|
||||
rol eax, cl
|
||||
add eax, [md5_b]
|
||||
push eax
|
||||
push dword [md5_b]
|
||||
push dword [md5_c]
|
||||
push dword [md5_d]
|
||||
pop dword [md5_a]
|
||||
pop dword [md5_d]
|
||||
pop dword [md5_c]
|
||||
pop dword [md5_b]
|
||||
pop cx
|
||||
inc cx
|
||||
cmp cx, 64
|
||||
jb main_loop
|
||||
; add to original values
|
||||
pop eax
|
||||
add [md5_a], eax
|
||||
pop eax
|
||||
add [md5_b], eax
|
||||
pop eax
|
||||
add [md5_c], eax
|
||||
pop eax
|
||||
add [md5_d], eax
|
||||
; advance pointers
|
||||
add si, 64
|
||||
pop cx
|
||||
inc cx
|
||||
cmp cx, [num_blocks]
|
||||
jne block_loop
|
||||
mov cx, 4
|
||||
mov si, md5_a
|
||||
pop di
|
||||
rep movsd
|
||||
popa
|
||||
ret
|
||||
|
||||
section .data
|
||||
|
||||
INIT_A equ 0x67452301
|
||||
INIT_B equ 0xEFCDAB89
|
||||
INIT_C equ 0x98BADCFE
|
||||
INIT_D equ 0x10325476
|
||||
|
||||
SHIFT_AMTS db 7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21
|
||||
|
||||
TABLE_T dd 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391
|
||||
BUFFER_INDEX_TABLE dw 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 4, 24, 44, 0, 20, 40, 60, 16, 36, 56, 12, 32, 52, 8, 28, 48, 20, 32, 44, 56, 4, 16, 28, 40, 52, 0, 12, 24, 36, 48, 60, 8, 0, 28, 56, 20, 48, 12, 40, 4, 32, 60, 24, 52, 16, 44, 8, 36
|
||||
ending_bytes_block_num dw 0
|
||||
ending_bytes times 128 db 0
|
||||
message_len dw 0
|
||||
num_blocks dw 0
|
||||
md5_a dd 0
|
||||
md5_b dd 0
|
||||
md5_c dd 0
|
||||
md5_d dd 0
|
||||
|
||||
display_str_1 db '0x$'
|
||||
display_str_2 db ' <== "$'
|
||||
display_str_3 db '"', 13, 10, '$'
|
||||
|
||||
test_input_1:
|
||||
test_input_1_len equ $ - test_input_1
|
||||
test_input_2 db 'a'
|
||||
test_input_2_len equ $ - test_input_2
|
||||
test_input_3 db 'abc'
|
||||
test_input_3_len equ $ - test_input_3
|
||||
test_input_4 db 'message digest'
|
||||
test_input_4_len equ $ - test_input_4
|
||||
test_input_5 db 'abcdefghijklmnopqrstuvwxyz'
|
||||
test_input_5_len equ $ - test_input_5
|
||||
test_input_6 db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
test_input_6_len equ $ - test_input_6
|
||||
test_input_7 db '12345678901234567890123456789012345678901234567890123456789012345678901234567890'
|
||||
test_input_7_len equ $ - test_input_7
|
||||
Loading…
Add table
Add a link
Reference in a new issue