%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich %% http://www.iis.ee.ethz.ch/~sha3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function hashval = Hamsi256(data, databitlen) %leftbits = 0; counter = 0; % hashbitlen = 256; rounds = 3; pfrounds = 6; cvsize = 256; index = 1; % iv256 = {'76657273', '69746569', '74204c65', '7576656e', '2c204465', '70617274', '656d656e', '7420456c'}; iv256 = {'76657273', '69746569', '74204c65', '7576656e', '2c204b61', '74686f6c', '69656b65', '20556e69'}; state = hex2dec(iv256); bits2hash = databitlen; s_blocksize = cvsize/8; % 32 bit msg = zeros(ceil(databitlen/s_blocksize),4); for i=1:ceil(databitlen/s_blocksize) for j=1:4 msg(i,j) = bitor(bitshift(hex2dec(data(i, 2*j-1)),4), hex2dec(data(i, 2*j))); end end leftdata = ones(1,8); block = msg; % expansion % for i=1:ceil(bits2hash/s_blocksize) % for j=1:4 % % block(i,j) = msg(j+4*(i-1)); % block(i,j) = block(i,j) + 1; % end % end % ---------------------------------------------- for i=1:floor(bits2hash/s_blocksize) state = hash256(rounds, state, block(index,:), 1); index = index + 1; counter = counter + 1; bits2hash = bits2hash - s_blocksize; end leftbits = bits2hash; for i=1:floor((bits2hash+7)/8) leftdata(i) = block(index,i); end length = cvsize*counter + leftbits; length = uint64(length); lenbytes = zeros(1,8); for i=1:8 lenbytes(i) = bitand(bitshift(length,-(8*(8-i))),255); end %expansion %lenbytes = lenbytes + 1; if isequal(leftbits, 0) state = hash256(rounds, state, lenbytes(1:4), 1); state = hash256(pfrounds, state, lenbytes(5:8), 2); else state = hash256(rounds, state, leftdata, 1); state = hash256(rounds, state, lenbytes(1:4), 1); state = hash256(pfrounds, state, lenbytes(5:8), 2); end state = dec2hex(state); hashval = state(1,:); for i=2:(size(state,2)) hashval= cat(2, hashval,state(i,:)); end end function state = hash256(rounds, cv, d, lastiter) alpha = { { {'ff00f0f0', 'ccccaaaa', 'f0f0cccc', 'ff00aaaa', 'ccccaaaa', 'f0f0ff00', 'aaaacccc', 'f0f0ff00'}; {'f0f0cccc', 'aaaaff00', 'ccccff00', 'aaaaf0f0', 'aaaaf0f0', 'ff00cccc', 'ccccf0f0', 'ff00aaaa'}; {'ccccaaaa', 'ff00f0f0', 'ff00aaaa', 'f0f0cccc', 'f0f0ff00', 'ccccaaaa', 'f0f0ff00', 'aaaacccc'}; {'aaaaff00', 'f0f0cccc', 'aaaaf0f0', 'ccccff00', 'ff00cccc', 'aaaaf0f0', 'ff00aaaa', 'ccccf0f0'} },{ {'caf9639c', '0ff0f9c0', '639c0ff0', 'caf9f9c0', '0ff0f9c0', '639ccaf9', 'f9c00ff0', '639ccaf9'}; {'639c0ff0', 'f9c0caf9', '0ff0caf9', 'f9c0639c', 'f9c0639c', 'caf90ff0', '0ff0639c', 'caf9f9c0'}; {'0ff0f9c0', 'caf9639c', 'caf9f9c0', '639c0ff0', '639ccaf9', '0ff0f9c0', '639ccaf9', 'f9c00ff0'}; {'f9c0caf9', '639c0ff0', 'f9c0639c', '0ff0caf9', 'caf90ff0', 'f9c0639c', 'caf9f9c0', '0ff0639c'} } }; state = zeros(1,8); s = zeros(5,4,'uint32'); % expansion + concatenation ind=[3,4,1,2]; for i=1:4 s(ceil(i/2), i) = Exp256(i, d); s(ceil(i/2),ind(i)) = cv(i); end for i=1:4 s(ceil(i/2)+2, i) = Exp256(i+4, d); s(ceil(i/2)+2,ind(i)) = cv(i+4); end % G expansion % tmp = GExp256(d); % ind2=[1,2,3,4,1,2,3,4]; % for i=1:8 % s(ceil(i/2),ind2(i))=tmp(i); % end %------------------------------- % non-linear permutation for i=1:rounds for r=1:4 for c=1:4 s(r,c) = bitxor(s(r,c), hex2dec(alpha{lastiter}{r}(c))); end end s(1,2) = bitxor(s(1,2), (i-1)); s = subst256(s); s = diffuse256(s); end % truncation for i=1:4 state(i) = bitxor(cv(i),s(1,i)); state(i+4) = bitxor(cv(i+4),s(3,i)); end end function s = subst256(s) s = Mov(5,1,s); s = And(1,3,s); s = Xor(1,4,s); s = Xor(3,2,s); s = Xor(3,1,s); s = Or(4,5,s); s = Xor(4,2,s); s = Xor(5,3,s); s = Mov(2,4,s); s = Or(4,5,s); s = Xor(4,1,s); s = And(1,2,s); s = Xor(5,1,s); s = Xor(2,4,s); s = Xor(2,5,s); s = Not(5,5,s); s = Mov(1,3,s); s = Mov(3,2,s); s = Mov(2,4,s); s = Mov(4,5,s); end function s = Mov(r,y,s) for i=1:4 s(r,i) = s(y,i); end end function s = Xor(r,y,s) for i=1:4 s(r,i) = bitxor(s(r,i),s(y,i)); end end function s = Or(r,y,s) for i=1:4 s(r,i) = bitor(s(r,i),s(y,i)); end end function s = And(r,y,s) for i=1:4 s(r,i) = bitand(s(r,i),s(y,i)); end end function s = Not(r,y,s) for i=1:4 s(r,i) = bitcmp(s(y,i),32); end end function s = diffuse256(s) [s(1,1),s(2,2),s(3,3),s(4,4)] = L(s(1,1),s(2,2),s(3,3),s(4,4)); [s(1,2),s(2,3),s(3,4),s(4,1)] = L(s(1,2),s(2,3),s(3,4),s(4,1)); [s(1,3),s(2,4),s(3,1),s(4,2)] = L(s(1,3),s(2,4),s(3,1),s(4,2)); [s(1,4),s(2,1),s(3,2),s(4,3)] = L(s(1,4),s(2,1),s(3,2),s(4,3)); end function [a,b,c,d] = L(a,b,c,d) a = bin2dec(circshift(dec2bin(a,32),[0,-13])); c = bin2dec(circshift(dec2bin(c,32),[0,-3])); b = bitxor(b,bitxor(a,c)); d = bitxor(d,bitxor(c,bitshift(a,3,32))); b = bin2dec(circshift(dec2bin(b,32),[0,-1])); d = bin2dec(circshift(dec2bin(d,32),[0,-7])); a = bitxor(a,bitxor(b,d)); c = bitxor(c,bitxor(d,bitshift(b,7,32))); a = bin2dec(circshift(dec2bin(a,32),[0,-5])); c = bin2dec(circshift(dec2bin(c,32),[0,-22])); end