shithub: mc

ref: 74d91a0021de012908cfdb35fb61a1473a376130
dir: /lib/crypto/sha1.myr/

View raw version
use std
use "hash"

pkg crypto =
	type sha1

	impl hash sha1

	/* legacy/convenience */
	const sha1	: (data : byte[:] -> byte[20])
	const sha1init	: (st : sha1# -> void)
	const sha1add	: (st : sha1#, data : byte[:] -> void)
	const sha1fin	: (st : sha1# -> byte[20])
;;

type sha1 = struct
	a : uint32
	b : uint32
	c : uint32
	d : uint32
	e : uint32
	tail : byte[64]
	msglen : uint64
;;

const sha1 = {data
	var st

	sha1init(&st)
	sha1add(&st, data)
	-> sha1fin(&st)
}

const sha1init = {st
	hinit(st)
}

const sha1add = {st, msg
	hadd(st, msg)
}

const sha1fin = {st
	var r : byte[20]
	hfin(st, r[:])
	-> r
}

impl hash sha1 =
	Blocksz = 64
	Hashsz = 20

	hinit = {st
		st.a = 0x67452301
		st.b = 0xefcdab89
		st.c = 0x98badcfe
		st.d = 0x10325476
		st.e = 0xc3d2e1f0
		st.msglen = 0
	}

	hadd = {st, data
		var n, ntail

		ntail = st.msglen % 64
		st.msglen += data.len
		if ntail > 0
			n = std.min(64 - ntail, data.len)
			std.slcp(st.tail[ntail:ntail + n], data[:n])
			data = data[n:]
			if n + ntail < 64
				-> void
			;;
			step(st, st.tail[:])
		;;

		while data.len >= 64
			step(st, data[:64])
			data = data[64:]
		;;

		std.slcp(st.tail[:data.len], data)
	}

	hfin = {st, r
		var ntail

		/* append first padding block */
		ntail = st.msglen % 64
		st.tail[ntail++] = 0x80
		std.slfill(st.tail[ntail:], 0)
		if 64 - ntail < 8
			step(st, st.tail[:])
			std.slfill(st.tail[:], 0)
		;;


		/* append size block */
		st.tail[56] = ((st.msglen * 8) >> 56	: byte)
		st.tail[57] = ((st.msglen * 8) >> 48	: byte)
		st.tail[58] = ((st.msglen * 8) >> 40	: byte)
		st.tail[59] = ((st.msglen * 8) >> 32	: byte)
		st.tail[60] = ((st.msglen * 8) >> 24	: byte)
		st.tail[61] = ((st.msglen * 8) >> 16	: byte)
		st.tail[62] = ((st.msglen * 8) >> 8	: byte)
		st.tail[63] = ((st.msglen * 8) >> 0	: byte)
		step(st, st.tail[:])

		r[0]  = (st.a >> 24	: byte)
		r[1]  = (st.a >> 16	: byte)
		r[2]  = (st.a >> 8	: byte)
		r[3]  = (st.a >> 0	: byte)
		r[4]  = (st.b >> 24	: byte)
		r[5]  = (st.b >> 16	: byte)
		r[6]  = (st.b >> 8	: byte)
		r[7]  = (st.b >> 0	: byte)
		r[8]  = (st.c >> 24	: byte)
		r[9]  = (st.c >> 16	: byte)
		r[10] = (st.c >> 8	: byte)
		r[11] = (st.c >> 0	: byte)
		r[12] = (st.d >> 24	: byte)
		r[13] = (st.d >> 16	: byte)
		r[14] = (st.d >> 8	: byte)
		r[15] = (st.d >> 0	: byte)
		r[16] = (st.e >> 24	: byte)
		r[17] = (st.e >> 16	: byte)
		r[18] = (st.e >> 8	: byte)
		r[19] = (st.e >> 0	: byte)
	}
;;

const K0 = 0x5a827999
const K1 = 0x6ed9eba1
const K2 = 0x8f1bbcdc
const K3 = 0xCA62C1D6
const step = {st, msg
        var a, b, c, d, e
	var s00, s01, s02, s03, s04, s05, s06, s07
	var s08, s09, s10, s11, s12, s13, s14, s15
        var t

        a = st.a
        b = st.b
        c = st.c
        d = st.d
        e = st.e

        s00 = unpack(msg[ 0: 4])
        s01 = unpack(msg[ 4: 8])
        s02 = unpack(msg[ 8:12])
        s03 = unpack(msg[12:16])
        s04 = unpack(msg[16:20])
        s05 = unpack(msg[20:24])
        s06 = unpack(msg[24:28])
        s07 = unpack(msg[28:32])
        s08 = unpack(msg[32:36])
        s09 = unpack(msg[36:40])
        s10 = unpack(msg[40:44])
        s11 = unpack(msg[44:48])
        s12 = unpack(msg[48:52])
        s13 = unpack(msg[52:56])
        s14 = unpack(msg[56:60])
        s15 = unpack(msg[60:64])

        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s00 + K0;  b = b << 30 | b >> 2
        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s01 + K0;  a = a << 30 | a >> 2
        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s02 + K0;  e = e << 30 | e >> 2
        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s03 + K0;  d = d << 30 | d >> 2
        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s04 + K0;  c = c << 30 | c >> 2
        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s05 + K0;  b = b << 30 | b >> 2
        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s06 + K0;  a = a << 30 | a >> 2
        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s07 + K0;  e = e << 30 | e >> 2
        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s08 + K0;  d = d << 30 | d >> 2
        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s09 + K0;  c = c << 30 | c >> 2
        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s10 + K0;  b = b << 30 | b >> 2
        d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s11 + K0;  a = a << 30 | a >> 2
        c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s12 + K0;  e = e << 30 | e >> 2
        b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s13 + K0;  d = d << 30 | d >> 2
        a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s14 + K0;  c = c << 30 | c >> 2
        e += (a << 5 | a >> 27) + (d ^ (b & (c ^ d))) + s15 + K0;  b = b << 30 | b >> 2


        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (c ^ (a & (b ^ c))) + s00 + K0;  a = a << 30 | a >> 2
        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (b ^ (e & (a ^ b))) + s01 + K0;  e = e << 30 | e >> 2
        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (a ^ (d & (e ^ a))) + s02 + K0;  d = d << 30 | d >> 2
        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (e ^ (c & (d ^ e))) + s03 + K0;  c = c << 30 | c >> 2
        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s04 + K1;  b = b << 30 | b >> 2
        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s05 + K1;  a = a << 30 | a >> 2
        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s06 + K1;  e = e << 30 | e >> 2
        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s07 + K1;  d = d << 30 | d >> 2
        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s08 + K1;  c = c << 30 | c >> 2
        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s09 + K1;  b = b << 30 | b >> 2
        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s10 + K1;  a = a << 30 | a >> 2
        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s11 + K1;  e = e << 30 | e >> 2
        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s12 + K1;  d = d << 30 | d >> 2
        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s13 + K1;  c = c << 30 | c >> 2
        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s14 + K1;  b = b << 30 | b >> 2
        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s15 + K1;  a = a << 30 | a >> 2
        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s00 + K1;  e = e << 30 | e >> 2
        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s01 + K1;  d = d << 30 | d >> 2
        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s02 + K1;  c = c << 30 | c >> 2
        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s03 + K1;  b = b << 30 | b >> 2
        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s04 + K1;  a = a << 30 | a >> 2
        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s05 + K1;  e = e << 30 | e >> 2
        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s06 + K1;  d = d << 30 | d >> 2
        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s07 + K1;  c = c << 30 | c >> 2

        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s08 + K2;  b = b << 30 | b >> 2
        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s09 + K2;  a = a << 30 | a >> 2
        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s10 + K2;  e = e << 30 | e >> 2
        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s11 + K2;  d = d << 30 | d >> 2
        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s12 + K2;  c = c << 30 | c >> 2
        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s13 + K2;  b = b << 30 | b >> 2
        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s14 + K2;  a = a << 30 | a >> 2
        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s15 + K2;  e = e << 30 | e >> 2
        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s00 + K2;  d = d << 30 | d >> 2
        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s01 + K2;  c = c << 30 | c >> 2
        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s02 + K2;  b = b << 30 | b >> 2
        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s03 + K2;  a = a << 30 | a >> 2
        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s04 + K2;  e = e << 30 | e >> 2
        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s05 + K2;  d = d << 30 | d >> 2
        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s06 + K2;  c = c << 30 | c >> 2
        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + ((b & (c | d)) | (c & d)) + s07 + K2;  b = b << 30 | b >> 2
        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + ((a & (b | c)) | (b & c)) + s08 + K2;  a = a << 30 | a >> 2
        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + ((e & (a | b)) | (a & b)) + s09 + K2;  e = e << 30 | e >> 2
        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + ((d & (e | a)) | (e & a)) + s10 + K2;  d = d << 30 | d >> 2
        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + ((c & (d | e)) | (d & e)) + s11 + K2;  c = c << 30 | c >> 2

        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s12 + K3;  b = b << 30 | b >> 2
        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s13 + K3;  a = a << 30 | a >> 2
        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s14 + K3;  e = e << 30 | e >> 2
        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s15 + K3;  d = d << 30 | d >> 2
        t = s13 ^ s08 ^ s02 ^ s00;  s00 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s00 + K3;  c = c << 30 | c >> 2
        t = s14 ^ s09 ^ s03 ^ s01;  s01 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s01 + K3;  b = b << 30 | b >> 2
        t = s15 ^ s10 ^ s04 ^ s02;  s02 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s02 + K3;  a = a << 30 | a >> 2
        t = s00 ^ s11 ^ s05 ^ s03;  s03 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s03 + K3;  e = e << 30 | e >> 2
        t = s01 ^ s12 ^ s06 ^ s04;  s04 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s04 + K3;  d = d << 30 | d >> 2
        t = s02 ^ s13 ^ s07 ^ s05;  s05 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s05 + K3;  c = c << 30 | c >> 2
        t = s03 ^ s14 ^ s08 ^ s06;  s06 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s06 + K3;  b = b << 30 | b >> 2
        t = s04 ^ s15 ^ s09 ^ s07;  s07 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s07 + K3;  a = a << 30 | a >> 2
        t = s05 ^ s00 ^ s10 ^ s08;  s08 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s08 + K3;  e = e << 30 | e >> 2
        t = s06 ^ s01 ^ s11 ^ s09;  s09 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s09 + K3;  d = d << 30 | d >> 2
        t = s07 ^ s02 ^ s12 ^ s10;  s10 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s10 + K3;  c = c << 30 | c >> 2
        t = s08 ^ s03 ^ s13 ^ s11;  s11 = t << 1 | t >> 31;  e += (a << 5 | a >> 27) + (b ^ c ^ d) + s11 + K3;  b = b << 30 | b >> 2
        t = s09 ^ s04 ^ s14 ^ s12;  s12 = t << 1 | t >> 31;  d += (e << 5 | e >> 27) + (a ^ b ^ c) + s12 + K3;  a = a << 30 | a >> 2
        t = s10 ^ s05 ^ s15 ^ s13;  s13 = t << 1 | t >> 31;  c += (d << 5 | d >> 27) + (e ^ a ^ b) + s13 + K3;  e = e << 30 | e >> 2
        t = s11 ^ s06 ^ s00 ^ s14;  s14 = t << 1 | t >> 31;  b += (c << 5 | c >> 27) + (d ^ e ^ a) + s14 + K3;  d = d << 30 | d >> 2
        t = s12 ^ s07 ^ s01 ^ s15;  s15 = t << 1 | t >> 31;  a += (b << 5 | b >> 27) + (c ^ d ^ e) + s15 + K3;  c = c << 30 | c >> 2

        st.a += a
        st.b += b
        st.c += c
        st.d += d
        st.e += e
}

const unpack = {b
	var v : uint32

	v = 0
	v |= (b[0] : uint32) << 24
	v |= (b[1] : uint32) << 16
	v |= (b[2] : uint32) << 8
	v |= (b[3] : uint32) << 0
	-> v
}