function [C,rc] = buildconstants(R,vb)

% Builds the Whirlpool constants from the substitution box.
% 
% 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 < 1; R = 10; end % Assume 10 rounds.
if nargin < 2; vb = 0; end % Assume no verbose output.

% The substitution box.
sbox = [];
sbox = [sbox '1823' 'c6E8' '87B8' '014F' '36A6' 'd2F5' '796F' '9152'];
sbox = [sbox '60Bc' '9B8E' 'A30c' '7B35' '1dE0' 'd7c2' '2E4B' 'FE57'];
sbox = [sbox '1577' '37E5' '9FF0' '4AdA' '58c9' '290A' 'B1A0' '6B85'];
sbox = [sbox 'Bd5d' '10F4' 'cB3E' '0567' 'E427' '418B' 'A77d' '95d8'];
sbox = [sbox 'FBEE' '7c66' 'dd17' '479E' 'cA2d' 'BF07' 'Ad5A' '8333'];
sbox = [sbox '6302' 'AA71' 'c819' '49d9' 'F2E3' '5B88' '9A26' '32B0'];
sbox = [sbox 'E90F' 'd580' 'BEcd' '3448' 'FF7A' '905F' '2068' '1AAE'];
sbox = [sbox 'B454' '9322' '64F1' '7312' '4008' 'c3Ec' 'dBA1' '8d3d'];
sbox = [sbox '9700' 'cF2B' '7682' 'd61B' 'B5AF' '6A50' '45F3' '30EF'];
sbox = [sbox '3F55' 'A2EA' '65BA' '2Fc0' 'dE1c' 'Fd4d' '9275' '068A'];
sbox = [sbox 'B2E6' '0E1F' '62d4' 'A896' 'F9c5' '2559' '8472' '394c'];
sbox = [sbox '5E78' '388c' 'd1A5' 'E261' 'B321' '9c1E' '43c7' 'Fc04'];
sbox = [sbox '5199' '6d0d' 'FAdF' '7E24' '3BAB' 'cE11' '8F4E' 'B7EB'];
sbox = [sbox '3c81' '94F7' 'B913' '2cd3' 'E76E' 'c403' '5644' '7FA9'];
sbox = [sbox '2ABB' 'c153' 'dc0B' '9d6c' '3174' 'F646' 'Ac89' '14E1'];
sbox = [sbox '163A' '6909' '70B6' 'd0Ed' 'cc42' '98A4' '285c' 'F886'];
C = zeros(8,256,64);
rc = zeros(R+1,64);
for x = 0:255
    c = hex2bv(sbox(floor(x/2)*4+1:floor(x/2)*4+4));
    if sum(dec2bv(x)&dec2bv(1)) == 0
        v1 = bvshift(c,-8);
    else
        v1 = c&hex2bv('FF');
    end
    v2 = bvshift(v1,1);
    if bv2dec(v2) >= hex2dec('100')
        v2 = xor(v2,hex2bv('11D'));
    end
    v4 = bvshift(v2,1);
    if bv2dec(v4) >= hex2dec('100')
        v4 = xor(v4,hex2bv('11D'));
    end
    v5 = xor(v4,v1);
    v8 = bvshift(v4,1);
    if bv2dec(v8) >= hex2dec('100')
        v8 = xor(v8,hex2bv('11D'));
    end
    v9 = xor(v8,v1);
    % Build the circulant table C[0][x] = S[x].[1, 1, 4, 1, 8, 5, 2, 9].
    C(1,x+1,:) = bvshift(v1,56)|bvshift(v1,48)|bvshift(v4,40)|bvshift(v1,32)|bvshift(v8,24)|bvshift(v5,16)|bvshift(v2,8)|v9;
    % Build the remaining circulant tables C[t][x] = C[0][x] rotated by t.
    for t = 2:8
        C(t,x+1,:) = bvshift(C(t-1,x+1,:),-8)|bvshift(C(t-1,x+1,:),56);
    end
    % Build the round constants.
    for r = 2:R+1
        i = 8*(r-2)+1;
        rc(r,:) = or(rc(r,:),reshape(C(1,i,:),[1 64])&hex2bv('FF00000000000000'));
        rc(r,:) = or(rc(r,:),reshape(C(2,i+1,:),[1 64])&hex2bv('00FF000000000000'));
        rc(r,:) = or(rc(r,:),reshape(C(3,i+2,:),[1 64])&hex2bv('0000FF0000000000'));
        rc(r,:) = or(rc(r,:),reshape(C(4,i+3,:),[1 64])&hex2bv('000000FF00000000'));
        rc(r,:) = or(rc(r,:),reshape(C(5,i+4,:),[1 64])&hex2bv('00000000FF000000'));
        rc(r,:) = or(rc(r,:),reshape(C(6,i+5,:),[1 64])&hex2bv('0000000000FF0000'));
        rc(r,:) = or(rc(r,:),reshape(C(7,i+6,:),[1 64])&hex2bv('000000000000FF00'));
        rc(r,:) = or(rc(r,:),reshape(C(8,i+7,:),[1 64])&hex2bv('00000000000000FF'));
    end
end
if vb
    disp('rc:')
    for i = 1:R+1
        disp(['   ' bv2hex(rc(i,:))])
    end
    disp(['C0(256) = ' num2str(bv2hex(reshape(C(1,256,:),[1 64])))])
end