function [hash,K] = processbuffer(C,rc,R,buffer,hash,vb)

% The core Whirlpool transform.
% 
% Copyright (c) 2008 Karl J A Petre and Xavier J Ortiz.
% This file was last updated 7 December 2008.
% 
% This code is included with the Matlab Whirlpool package.
% 
% The Whirlpool algorithm was developed by:
%     Paulo S. L. M. Barreto (pbarreto@scopus.com.br)
%     Vincent Rijmen (vincent.rijmen@cryptomathic.com)
% 
% This software is provided by the author as is and any express
% or implied warranties, including, but not limited to, the implied 
% warranties of merchantability and fitness for a particular purpose
% are disclaimed. In no event shall the author or contributors be
% liable for any direct, indirect, incidental, special, exemplary, or
% consequential damages (including, but not limited to, procurement of
% substitute goods or services; loss of use, data, or profits; or 
% business interruption) however caused and on any theory of liability,
% whether in contract, strict liability, or tort (including negligence
% or otherwise) arising in any way out of the use of this software,
% even if advised on the possibility of such damage.

if nargin < 5; vb = 0; end % Assume no verbose output.

if vb
    disp('Z'':')
    for i = 1:8:57
        disp(['   ' pp(buffer(i,:)) pp(buffer(i+1,:)) pp(buffer(i+2,:)) pp(buffer(i+3,:)) pp(buffer(i+4,:)) pp(buffer(i+5,:)) pp(buffer(i+6,:)) pp(buffer(i+7,:))])
    end
end

% The hashing state.
K = zeros(8,64);
L = zeros(8,64);
block = zeros(8,64);
state = zeros(8,64);

% Map the buffer to a block.
for i = 1:8
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+1,:),56));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+2,:),48));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+3,:),40));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+4,:),32));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+5,:),24));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+6,:),16));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+7,:),8));
    block(i,:) = xor(block(i,:),bvshift(buffer((i-1)*8+8,:),0));
end
% Compute and apply K^0 to the cipher state.
if vb disp(['K0,X'''':']); end
for i = 1:8
    K(i,:) = hash(i,:);
    state(i,:) = xor(block(i,:),K(i,:));
    if vb disp(['   ' pp(K(i,:)) '   ' pp(state(i,:))]); end
end
% Iterate over all rounds.
for r = 1:R
    % Compute K^r from K^(r-1).
    for i = 1:8
        L(i,:) = zeros(1,64);
        for t = 7:-1:0
            L(i,:) = xor(L(i,:),reshape(C(8-t,bv2dec(bvshift(K(mod(i+t,8)+1,:),-8*t)&hex2bv('FF'))+1,:),[1 64]));
        end
    end
    L(1,:) = xor(L(1,:),rc(r+1,:));
    K = L;
    % Apply the r-th round transformation.
    for i = 1:8
        for t = 7:-1:0
            L(i,:) = xor(L(i,:),reshape(C(8-t,bv2dec(bvshift(state(mod(i+t,8)+1,:),-8*t)&hex2bv('FF'))+1,:),[1 64]));
        end
    end
    state = L;
    if vb
        disp(['K' num2str(r) ',W''' num2str(r) ':'])
        for i = 1:8
            disp(['   ' pp(K(i,:)) '   ' pp(state(i,:))])
        end
    end
end
% Apply the Miyaguchi-Preneel compression function.
for i = 1:8
    hash(i,:) = xor(hash(i,:),xor(state(i,:),block(i,:)));
end
if vb
    disp(['Y'':'])
    for i = 1:8
        disp(['   ' pp(hash(i,:))])
    end
end