%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Copyright: 2010 Integrated Sytems Laboratory, ETH Zurich
%% http://www.iis.ee.ethz.ch/~sha3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function hashval = Keccak256(data, databitlen)
hashbitlen=256;
capacity=512;
rate=1088;
%diversifier=hashbitlen/8; % 32
rounds_nr=24;
block_len=64;
block_num=(rate+capacity)/block_len;
r_num=rate/block_len;
msg=zeros(ceil(databitlen/rate),block_num,'uint64');
for i=1:ceil(databitlen/rate)
for j=1:r_num
msg(i,j) = hex2dec64(data(i,(j-1)*16+1:j*16));
end
end
round_constants=keccak_round_constants(rounds_nr);
rho_offsets=keccak_rho_offsets();
state=zeros(1,block_num,'uint64');
for i=1:ceil(databitlen/rate)
state=bitxor(state, msg(i,:));
state=reverse(state);
%hdisplay(msg(i,:), 'input before permutation');
state=KeccakPermutation(state, rounds_nr, round_constants, rho_offsets);
state=reverse(state);
%hdisplay(state, 'state after permutation');
end
pad='01';
%pad='10';
enc_d='20'; % enc(d,8)
%enc_d='04';
enc_r='88'; % enc(r/8,8)
%enc_r='01';
finalstate=[pad, enc_d, enc_r, pad, sprintf('%0264X',0)];
endmsg=zeros(1,block_num,'uint64');
for j=1:r_num
endmsg(j) = hex2dec64(finalstate((j-1)*16+1:j*16));
end
state=bitxor(state, endmsg);
state=reverse(state);
%hdisplay(state, 'input state before final permutation');
state=KeccakPermutation(state, rounds_nr, round_constants, rho_offsets);
state=reverse(state);
%hdisplay(state, 'state after final permutation');
for i=1:block_num
tmp0=dec2hex(uint32(bitand(bitshift(state(i),-32),2^32-1)),8);
tmp1=dec2hex(uint32(bitand(state(i),2^32-1)),8);
hexval= cat(2,tmp0,tmp1);
if i==1
hashval=hexval;
else
hashval=cat(2,hashval,hexval);
end
end
hashval=hashval(1,1:hashbitlen/4);
end