%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 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





Generated on Fri Sep 24 10:39:12 CEST 2010
Home