Some small hash loop tweaks and I increased the number of hash rounds from 3 to 4 also:
import os,sys
def tt(ll):
return (ll & 0xffffffff)
def sdbm(inpt, leng):
hshs = 0
for x in range(0, leng):
hshs = tt(ord(inpt[x]) + tt(hshs << 6) + tt(hshs << 16) - hshs)
return hshs
def sdbm_hash(inpt, leng):
mixs = [1, 6, 16, 13, 33, 27, 67, 55, 123]
hshs = [0, 0, 0, 0, 0, 0, 0, 0, 0]
more = 0
mlen = len(hshs) ; rnds = (4 * mlen)
for x in range(0, mlen+leng):
hshs[0] = tt(mixs[x%mlen] + ord(inpt[x%leng]) + (hshs[0] << 6) + (hshs[0] << 16) - hshs[0])
more = (more ^ (hshs[0] >> 16))
i = ((x % (mlen - 1)) + 1)
less = ((hshs[i] & 0xffff0000) ^ ((hshs[i] & 0xffff) << 16))
hshs[i] = (less ^ more)
for z in range(0, rnds):
hshs[0] = tt(z + more + (hshs[0] << 6) + (hshs[0] << 16) - hshs[0])
more = (more ^ (hshs[mlen-1] >> 16))
for y in range(mlen-1, 0, -1):
hshs[y] = tt((hshs[y] << 16) | (hshs[y-1] >> 16))
hshs[y-1] = (hshs[y-1] & 0xffff)
o = ""
for h in hshs[1:]:
for x in range(3, -1, -1):
o += chr((h >> (x * 8)) & 0xff)
return o
def sdbm_hmac(mesg, mlen, skey, klen):
inner_pad = 0x36 ; outer_pad = 0x5C
block_size = 64 ; ikey = "" ; okey = ""
tkey = skey ; tlen = klen
if (klen > block_size):
tkey = sdbm_hash(skey, klen)
tlen = len(tkey)
for x in range(0, block_size):
c = 0
if (x < tlen):
c = ord(tkey[x])
ikey += chr(inner_pad ^ c)
okey += chr(outer_pad ^ c)
ihsh = sdbm_hash(ikey+mesg, block_size+mlen)
ilen = len(ihsh)
ohsh = sdbm_hash(okey+ihsh, block_size+ilen)
return ohsh
def stoh(s):
return "".join([hex(ord(c))[2:].rjust(2, '0') for c in s])
m = sys.argv[1] ; l = len(m)
k = sys.argv[2] ; n = len(k)
#print(stoh(sdbm_hash(m, l)), sdbm(m, l), m, l)
print(stoh(sdbm_hmac(m, l, k, n)), sdbm(m, l), m, l, sdbm(k, n), k, n)
$ for x in b c ; do for y in b c ; do python hash.py "$x" "$y" ; echo ; done ; done
('d805c892902cf6ea0c98d1946110a61334a9a1158b430fb7d1c5ba7afb29147d', 98, 'b', 1, 98, 'b', 1)
('6eb38871cc3679cb533f1daeee4ed87ab4f154f953e5ea96d508bda6bb054abd', 98, 'b', 1, 99, 'c', 1)
('0d034f1f7627492fd57bd92a63a8a4f2d977f02c2fdf29b4e49f4b3b21a9e738', 99, 'c', 1, 98, 'b', 1)
('09b2678c7ce46cd7cd112b4a2b6fd05d50c858fe0460d29264c4ea01595968db', 99, 'c', 1, 99, 'c', 1)
$ ./hash "this is a test" "b"
[6b18600ee98449472dd377755dd67cd436c9c143cfc893c9a2181e0567d16cf1] [1655286693] [this is a test] [14] [98] [b] [1]
$ ./hash "this is a test" "c"
[bd3bc1a983e35311e5ea60db5ae8cd28a821386937dfd480eccff95fab8356b9] [1655286693] [this is a test] [14] [99] [c] [1]
$ ./hash "this is a tesu" "b"
[8cddc8b9f5a1a1adf41c78b035bf59b444431e772b9c39824e2cf67e2837d9b0] [1655286694] [this is a tesu] [14] [98] [b] [1]
$ ./hash "this is a tesu" "c"
[2554d7d9ecb47d36b7f62d5e4432a7983490aca1229a91331c16b81567c4edff] [1655286694] [this is a tesu] [14] [99] [c] [1]
#include <stdio.h>
#include <string.h>
unsigned int sdbm(char *inpt, int leng) {
unsigned int hshs = 0;
for (int x = 0; x < leng; ++x) {
hshs = (inpt[x] + (hshs << 6) + (hshs << 16) - hshs);
}
return hshs;
}
void sdbm_hash(unsigned char *outp, unsigned char *inpt, int leng) {
unsigned int mixs[] = {1, 6, 16, 13, 33, 27, 67, 55, 123};
unsigned int hshs[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
unsigned int less, more = 0;
int i, mlen = 9, rnds = (4 * mlen);
for (int x = 0; x < (mlen+leng); ++x) {
hshs[0] = (mixs[x%mlen] + inpt[x%leng] + (hshs[0] << 6) + (hshs[0] << 16) - hshs[0]);
more = (more ^ (hshs[0] >> 16));
i = ((x % (mlen - 1)) + 1);
less = ((hshs[i] & 0xffff0000) ^ ((hshs[i] & 0xffff) << 16));
hshs[i] = (less ^ more);
}
for (int z = 0; z < rnds; ++z) {
hshs[0] = (z + more + (hshs[0] << 6) + (hshs[0] << 16) - hshs[0]);
more = (more ^ (hshs[mlen-1] >> 16));
for (int y = mlen-1; y > 0; --y) {
hshs[y] = ((hshs[y] << 16) | (hshs[y-1] >> 16));
hshs[y-1] = (hshs[y-1] & 0xffff);
}
}
for (int x = 1, y = 0; x < mlen; ++x) {
for (int z = 3; z > -1; --z, ++y) {
outp[y] = ((hshs[x] >> (z * 8)) & 0xff);
}
}
}
void sdbm_hmac(unsigned char *outp, unsigned char *mesg, int mlen, unsigned char *skey, int klen) {
int block_size = 64, hash_size = 32;
unsigned char inner_pad = 0x36, outer_pad = 0x5C;
unsigned char ikey[block_size], okey[block_size], ihsh[hash_size], thsh[hash_size];
unsigned char buff[block_size+mlen+hash_size];
unsigned char *tkey = skey; int tlen = klen;
if (klen > block_size) {
sdbm_hash(thsh, skey, klen);
tkey = thsh; tlen = hash_size;
}
for (int x = 0; x < block_size; ++x) {
unsigned char padc = 0;
if (x < tlen) { padc = tkey[x]; }
ikey[x] = (inner_pad ^ padc);
okey[x] = (outer_pad ^ padc);
}
bcopy(ikey, buff, block_size);
bcopy(mesg, buff+block_size, mlen);
sdbm_hash(ihsh, buff, block_size+mlen);
bcopy(okey, buff, block_size);
bcopy(ihsh, buff+block_size, hash_size);
sdbm_hash(outp, buff, block_size+hash_size);
}
void stoh(char *outp, unsigned char *inpt) {
char *hexs = "0123456789abcdef";
for (int x = 0, y = 0; x < 32; ++x) {
outp[y] = hexs[(inpt[x] >> 4) & 0xf]; ++y;
outp[y] = hexs[inpt[x] & 0xf]; ++y;
}
}
int main(int argc, char *argv[]) {
char *m = argv[1]; int l = strlen(m);
char *k = argv[2]; int n = strlen(k);
unsigned char h[32]; char o[65]; bzero(o, 65);
sdbm_hmac(h, (unsigned char *)m, l, (unsigned char *)k, n); stoh(o, h);
printf("[%s] [%u] [%s] [%d] [%u] [%s] [%d]\n", o, sdbm(m, l), m, l, sdbm(k, n), k, n);
return 0;
}