hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit b93439f8c7f1a14e5ee88671fa34e4a450c1f337
parent f914a9bde89c55749b11100377abf0bc479df109
Author: Drew DeVault <sir@cmpwn.com>
Date:   Mon, 10 Jan 2022 11:19:11 +0100

crypto::md5: drop module

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Dcrypto/md5/+test.ha | 34----------------------------------
Dcrypto/md5/md5.ha | 225-------------------------------------------------------------------------------
2 files changed, 0 insertions(+), 259 deletions(-)

diff --git a/crypto/md5/+test.ha b/crypto/md5/+test.ha @@ -1,34 +0,0 @@ -use fmt; -use hash; -use strings; -use encoding::hex; - -@test fn md5() void = { - let md5 = md5(); - const vectors = [ - ("", "d41d8cd98f00b204e9800998ecf8427e"), - ("abc", "900150983cd24fb0d6963f7d28e17f72"), - ("hello world", "5eb63bbbe01eeed093cb22bb8f5acdc3"), - ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "8215ef0796a20bcaaae116d3876c664a"), - ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "03dd8807a93175fb062dfb55dc7d359c"), - ("Hare is a cool language", "391601a424a3331251b7fbaaa073458d"), - ("'UNIX was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things' - Doug Gwyn", "e0d32da5235e0375e887d5dbff3bf44b"), - ("'Life is too short to run proprietary software' - Bdale Garbee", "09f9326df2fde54e53a15a6482c2bc26"), - ("'The central enemy of reliability is complexity.' - Geer et al", "839182c45d66fd79e8be1d9faacc1b00"), - ]; - - for (let i = 0z; i < len(vectors); i += 1) { - const vector = vectors[i]; - hash::reset(&md5); - hash::write(&md5, strings::toutf8(vector.0)); - - let sum: [SIZE]u8 = [0...]; - hash::sum(&md5, sum); - - let sumhex = hex::encodestr(sum); - if (sumhex != vector.1) { - fmt::errorfln("Vector {}: {} != {}", i, sumhex, vector.1)!; - abort(); - }; - }; -}; diff --git a/crypto/md5/md5.ha b/crypto/md5/md5.ha @@ -1,225 +0,0 @@ -use hash; -use io; -use crypto::math; -use endian; - -// The size, in bytes, of an MD5 digest. -export def SIZE: size = 16; - -def chunk: size = 64; -def init0: u32 = 0x67452301; -def init1: u32 = 0xEFCDAB89; -def init2: u32 = 0x98BADCFE; -def init3: u32 = 0x10325476; - -export type digest = struct { - hash::hash, - h: [4]u32, - x: [chunk]u8, - nx: size, - ln: size, -}; - -// Creates a [[hash::hash]] which computes a MD5 hash as defined in RFC 1321. -// Note that MD5 is cryptographically broken and should not be used for secure -// applications. Where possible, applications are encouraged to use -// [[crypto::sha256]] or [[crypto::sha512]] instead. -// -// This hash function does not allocate any state, so you do not have to call -// [[hash::close]] when you are done with it. -export fn md5() digest = { - let md5 = digest { - writer = &write, - sum = &sum, - reset = &reset, - sz = SIZE, - bsz = chunk, - ... - }; - hash::reset(&md5); - return md5; -}; - -// [[hash::createfunc]] to allocate a hash state to compute MD5 -export fn create() *hash::hash = alloc(md5()); - -fn write(st: *io::stream, buf: const []u8) (size | io::error) = { - let h = st: *digest; - let b: []u8 = buf; - let nn = len(buf); - - h.ln += nn; - - if (h.nx > 0) { - // Compute how many bytes can be copied into h.x - let r = len(h.x) - h.nx; - let n = if (nn > r) r else nn; - h.x[h.nx..] = b[..n]; - h.nx += n; - if (h.nx == chunk) { - block(h, h.x[..]); - h.nx = 0; - }; - b = b[n..]; - }; - if (len(b) >= chunk) { - let n = len(b) & ~(chunk - 1); - block(h, b[..n]); - b = b[n..]; - }; - if (len(b) > 0) { - let n = len(b); - h.x[..n] = b[..]; - h.nx = n; - }; - return nn; -}; - -fn reset(h: *hash::hash) void = { - let h = h: *digest; - h.h[0] = init0; - h.h[1] = init1; - h.h[2] = init2; - h.h[3] = init3; - h.nx = 0; - h.ln = 0; -}; - -fn sum(h: *hash::hash, buf: []u8) void = { - let h = h: *digest; - let copy = *h; - let h = &copy; - - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. - let ln = h.ln; - let tmp: [1 + 63 + 8]u8 = [0x80, 0...]; - const pad = (55 - ln) % 64; - endian::leputu32(tmp[1+pad..], (ln << 3) : u32); - write(h, tmp[..1+pad+8])!; // append the length in bits - - assert(h.nx == 0); - - // Where we write the digest - endian::leputu32(buf[0..], h.h[0]); - endian::leputu32(buf[4..], h.h[1]); - endian::leputu32(buf[8..], h.h[2]); - endian::leputu32(buf[12..], h.h[3]); -}; - -// A generic, pure Hare version of the MD5 block step -fn block(h: *digest, p: []u8) void = { - // load state - let a = h.h[0]; - let b = h.h[1]; - let c = h.h[2]; - let d = h.h[3]; - - for (len(p) >= chunk; p = p[chunk..]) { - - // save current state - let aa = a, bb = b, cc = c, dd = d; - - // load input block - let x0 = endian::legetu32(p[4 * 0x0..]); - let x0 = endian::legetu32(p[4 * 0x0..]); - let x1 = endian::legetu32(p[4 * 0x1..]); - let x2 = endian::legetu32(p[4 * 0x2..]); - let x3 = endian::legetu32(p[4 * 0x3..]); - let x4 = endian::legetu32(p[4 * 0x4..]); - let x5 = endian::legetu32(p[4 * 0x5..]); - let x6 = endian::legetu32(p[4 * 0x6..]); - let x7 = endian::legetu32(p[4 * 0x7..]); - let x8 = endian::legetu32(p[4 * 0x8..]); - let x9 = endian::legetu32(p[4 * 0x9..]); - let xa = endian::legetu32(p[4 * 0xa..]); - let xb = endian::legetu32(p[4 * 0xb..]); - let xc = endian::legetu32(p[4 * 0xc..]); - let xd = endian::legetu32(p[4 * 0xd..]); - let xe = endian::legetu32(p[4 * 0xe..]); - let xf = endian::legetu32(p[4 * 0xf..]); - - // round 1 - a = b + math::rotl32((((c^d)&b)^d)+a+x0+0xd76aa478, 7); - d = a + math::rotl32((((b^c)&a)^c)+d+x1+0xe8c7b756, 12); - c = d + math::rotl32((((a^b)&d)^b)+c+x2+0x242070db, 17); - b = c + math::rotl32((((d^a)&c)^a)+b+x3+0xc1bdceee, 22); - a = b + math::rotl32((((c^d)&b)^d)+a+x4+0xf57c0faf, 7); - d = a + math::rotl32((((b^c)&a)^c)+d+x5+0x4787c62a, 12); - c = d + math::rotl32((((a^b)&d)^b)+c+x6+0xa8304613, 17); - b = c + math::rotl32((((d^a)&c)^a)+b+x7+0xfd469501, 22); - a = b + math::rotl32((((c^d)&b)^d)+a+x8+0x698098d8, 7); - d = a + math::rotl32((((b^c)&a)^c)+d+x9+0x8b44f7af, 12); - c = d + math::rotl32((((a^b)&d)^b)+c+xa+0xffff5bb1, 17); - b = c + math::rotl32((((d^a)&c)^a)+b+xb+0x895cd7be, 22); - a = b + math::rotl32((((c^d)&b)^d)+a+xc+0x6b901122, 7); - d = a + math::rotl32((((b^c)&a)^c)+d+xd+0xfd987193, 12); - c = d + math::rotl32((((a^b)&d)^b)+c+xe+0xa679438e, 17); - b = c + math::rotl32((((d^a)&c)^a)+b+xf+0x49b40821, 22); - - // round 2 - a = b + math::rotl32((((b^c)&d)^c)+a+x1+0xf61e2562, 5); - d = a + math::rotl32((((a^b)&c)^b)+d+x6+0xc040b340, 9); - c = d + math::rotl32((((d^a)&b)^a)+c+xb+0x265e5a51, 14); - b = c + math::rotl32((((c^d)&a)^d)+b+x0+0xe9b6c7aa, 20); - a = b + math::rotl32((((b^c)&d)^c)+a+x5+0xd62f105d, 5); - d = a + math::rotl32((((a^b)&c)^b)+d+xa+0x02441453, 9); - c = d + math::rotl32((((d^a)&b)^a)+c+xf+0xd8a1e681, 14); - b = c + math::rotl32((((c^d)&a)^d)+b+x4+0xe7d3fbc8, 20); - a = b + math::rotl32((((b^c)&d)^c)+a+x9+0x21e1cde6, 5); - d = a + math::rotl32((((a^b)&c)^b)+d+xe+0xc33707d6, 9); - c = d + math::rotl32((((d^a)&b)^a)+c+x3+0xf4d50d87, 14); - b = c + math::rotl32((((c^d)&a)^d)+b+x8+0x455a14ed, 20); - a = b + math::rotl32((((b^c)&d)^c)+a+xd+0xa9e3e905, 5); - d = a + math::rotl32((((a^b)&c)^b)+d+x2+0xfcefa3f8, 9); - c = d + math::rotl32((((d^a)&b)^a)+c+x7+0x676f02d9, 14); - b = c + math::rotl32((((c^d)&a)^d)+b+xc+0x8d2a4c8a, 20); - - // round 3 - a = b + math::rotl32((b^c^d)+a+x5+0xfffa3942, 4); - d = a + math::rotl32((a^b^c)+d+x8+0x8771f681, 11); - c = d + math::rotl32((d^a^b)+c+xb+0x6d9d6122, 16); - b = c + math::rotl32((c^d^a)+b+xe+0xfde5380c, 23); - a = b + math::rotl32((b^c^d)+a+x1+0xa4beea44, 4); - d = a + math::rotl32((a^b^c)+d+x4+0x4bdecfa9, 11); - c = d + math::rotl32((d^a^b)+c+x7+0xf6bb4b60, 16); - b = c + math::rotl32((c^d^a)+b+xa+0xbebfbc70, 23); - a = b + math::rotl32((b^c^d)+a+xd+0x289b7ec6, 4); - d = a + math::rotl32((a^b^c)+d+x0+0xeaa127fa, 11); - c = d + math::rotl32((d^a^b)+c+x3+0xd4ef3085, 16); - b = c + math::rotl32((c^d^a)+b+x6+0x04881d05, 23); - a = b + math::rotl32((b^c^d)+a+x9+0xd9d4d039, 4); - d = a + math::rotl32((a^b^c)+d+xc+0xe6db99e5, 11); - c = d + math::rotl32((d^a^b)+c+xf+0x1fa27cf8, 16); - b = c + math::rotl32((c^d^a)+b+x2+0xc4ac5665, 23); - - // round 4 - a = b + math::rotl32((c^(b|~d))+a+x0+0xf4292244, 6); - d = a + math::rotl32((b^(a|~c))+d+x7+0x432aff97, 10); - c = d + math::rotl32((a^(d|~b))+c+xe+0xab9423a7, 15); - b = c + math::rotl32((d^(c|~a))+b+x5+0xfc93a039, 21); - a = b + math::rotl32((c^(b|~d))+a+xc+0x655b59c3, 6); - d = a + math::rotl32((b^(a|~c))+d+x3+0x8f0ccc92, 10); - c = d + math::rotl32((a^(d|~b))+c+xa+0xffeff47d, 15); - b = c + math::rotl32((d^(c|~a))+b+x1+0x85845dd1, 21); - a = b + math::rotl32((c^(b|~d))+a+x8+0x6fa87e4f, 6); - d = a + math::rotl32((b^(a|~c))+d+xf+0xfe2ce6e0, 10); - c = d + math::rotl32((a^(d|~b))+c+x6+0xa3014314, 15); - b = c + math::rotl32((d^(c|~a))+b+xd+0x4e0811a1, 21); - a = b + math::rotl32((c^(b|~d))+a+x4+0xf7537e82, 6); - d = a + math::rotl32((b^(a|~c))+d+xb+0xbd3af235, 10); - c = d + math::rotl32((a^(d|~b))+c+x2+0x2ad7d2bb, 15); - b = c + math::rotl32((d^(c|~a))+b+x9+0xeb86d391, 21); - - // add saved state - a += aa; - b += bb; - c += cc; - d += dd; - }; - - // save state - h.h[0] = a; - h.h[1] = b; - h.h[2] = c; - h.h[3] = d; -};