| 41561 |      1 | package body RMD is
 | 
|  |      2 | 
 | 
|  |      3 | 
 | 
|  |      4 | 
 | 
|  |      5 |    function F(J : Round_Index; X,Y,Z : Word) return Word
 | 
|  |      6 |    is
 | 
|  |      7 |       Result: Word;
 | 
|  |      8 |    begin
 | 
|  |      9 |       if     0 <= J and J <= 15 then Result := X xor Y xor Z;
 | 
|  |     10 |       elsif 16 <= J and J <= 31 then Result := (X and Y) or (not X and Z);
 | 
|  |     11 |       elsif 32 <= J and J <= 47 then Result := (X or not Y) xor Z;
 | 
|  |     12 |       elsif 48 <= J and J <= 63 then Result := (X and Z) or (Y and not Z);
 | 
|  |     13 |       else                           Result := X xor (Y or not Z);
 | 
|  |     14 |       end if;
 | 
|  |     15 |       return Result;
 | 
|  |     16 |    end F;
 | 
|  |     17 | 
 | 
|  |     18 | 
 | 
|  |     19 | 
 | 
|  |     20 |    function K_L(J : Round_Index) return Word
 | 
|  |     21 |    is
 | 
|  |     22 |       K: Word;
 | 
|  |     23 |    begin
 | 
|  |     24 |       if     0 <= J and J <= 15 then K := 16#0000_0000#;
 | 
|  |     25 |       elsif 16 <= J and J <= 31 then K := 16#5A82_7999#;
 | 
|  |     26 |       elsif 32 <= J and J <= 47 then K := 16#6ED9_EBA1#;
 | 
|  |     27 |       elsif 48 <= J and J <= 63 then K := 16#8F1B_BCDC#;
 | 
|  |     28 |       else                           K := 16#A953_FD4E#;
 | 
|  |     29 |       end if;
 | 
|  |     30 |       return K;
 | 
|  |     31 |    end K_L;
 | 
|  |     32 | 
 | 
|  |     33 | 
 | 
|  |     34 |    function K_R(J : Round_Index) return Word
 | 
|  |     35 |    is
 | 
|  |     36 |       K: Word;
 | 
|  |     37 |    begin
 | 
|  |     38 |       if     0 <= J and J <= 15 then K := 16#50A2_8BE6#;
 | 
|  |     39 |       elsif 16 <= J and J <= 31 then K := 16#5C4D_D124#;
 | 
|  |     40 |       elsif 32 <= J and J <= 47 then K := 16#6D70_3EF3#;
 | 
|  |     41 |       elsif 48 <= J and J <= 63 then K := 16#7A6D_76E9#;
 | 
|  |     42 |       else                           K := 16#0000_0000#;
 | 
|  |     43 |       end if;
 | 
|  |     44 |       return K;
 | 
|  |     45 |    end K_R;
 | 
|  |     46 | 
 | 
|  |     47 | 
 | 
|  |     48 | 
 | 
|  |     49 |    function R_L(J : Round_Index) return Block_Index
 | 
|  |     50 |    is
 | 
|  |     51 |       R_Values : constant Block_Permutation := Block_Permutation'
 | 
|  |     52 |         (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
 | 
|  |     53 |          7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
 | 
|  |     54 |          3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
 | 
|  |     55 |          1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
 | 
|  |     56 |          4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13);
 | 
|  |     57 |       --# for R_Values declare rule;
 | 
|  |     58 |    begin
 | 
|  |     59 |       return R_Values(J);
 | 
|  |     60 |    end R_L;
 | 
|  |     61 | 
 | 
|  |     62 | 
 | 
|  |     63 |    function R_R(J : Round_Index) return Block_Index
 | 
|  |     64 |    is
 | 
|  |     65 |       R_Values : constant Block_Permutation := Block_Permutation'
 | 
|  |     66 |         (5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
 | 
|  |     67 |          6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
 | 
|  |     68 |          15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
 | 
|  |     69 |          8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
 | 
|  |     70 |          12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11);
 | 
|  |     71 |       --# for R_Values declare rule;
 | 
|  |     72 |    begin
 | 
|  |     73 |       return R_Values(J);
 | 
|  |     74 |    end R_R;
 | 
|  |     75 | 
 | 
|  |     76 | 
 | 
|  |     77 |    function S_L(J : Round_Index) return Rotate_Amount
 | 
|  |     78 |    is
 | 
|  |     79 |       S_Values : constant Rotate_Definition := Rotate_Definition'
 | 
|  |     80 |         (11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
 | 
|  |     81 |          7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
 | 
|  |     82 |          11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
 | 
|  |     83 |          11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
 | 
|  |     84 |          9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6);
 | 
|  |     85 |       --# for S_Values declare rule;
 | 
|  |     86 |    begin
 | 
|  |     87 |       return S_Values(J);
 | 
|  |     88 |    end S_L;
 | 
|  |     89 | 
 | 
|  |     90 | 
 | 
|  |     91 |    function S_R(J : Round_Index) return Rotate_Amount
 | 
|  |     92 |    is
 | 
|  |     93 |       S_Values : constant Rotate_Definition := Rotate_Definition'
 | 
|  |     94 |         (8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
 | 
|  |     95 |          9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
 | 
|  |     96 |          9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
 | 
|  |     97 |          15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
 | 
|  |     98 |          8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11);
 | 
|  |     99 |       --# for S_Values declare rule;
 | 
|  |    100 |    begin
 | 
|  |    101 |       return S_Values(J);
 | 
|  |    102 |    end S_R;
 | 
|  |    103 | 
 | 
|  |    104 | 
 | 
|  |    105 | 
 | 
|  |    106 |    procedure Round(CA, CB, CC, CD, CE : in out Word; X : in Block)
 | 
|  |    107 |    is
 | 
|  |    108 |       CLA, CLB, CLC, CLD, CLE, CRA, CRB, CRC, CRD, CRE : Word;
 | 
|  |    109 |       T : Word;
 | 
|  |    110 |    begin
 | 
|  |    111 |       CLA := CA;
 | 
|  |    112 |       CLB := CB;
 | 
|  |    113 |       CLC := CC;
 | 
|  |    114 |       CLD := CD;
 | 
|  |    115 |       CLE := CE;
 | 
|  |    116 |       CRA := CA;
 | 
|  |    117 |       CRB := CB;
 | 
|  |    118 |       CRC := CC;
 | 
|  |    119 |       CRD := CD;
 | 
|  |    120 |       CRE := CE;
 | 
|  |    121 |       for J in Round_Index range 0..79
 | 
|  |    122 |       loop
 | 
|  |    123 |          -- left
 | 
|  |    124 |          T := Wordops.Rotate(S_L(J),
 | 
|  |    125 |                              CLA +
 | 
|  |    126 |                                F(J, CLB, CLC, CLD) +
 | 
|  |    127 |                                X(R_L(J)) +
 | 
|  |    128 |                                K_L(J)) +
 | 
|  |    129 |            CLE;
 | 
|  |    130 |          CLA := CLE;
 | 
|  |    131 |          CLE := CLD;
 | 
|  |    132 |          CLD := Wordops.Rotate(10, CLC);
 | 
|  |    133 |          CLC := CLB;
 | 
|  |    134 |          CLB := T;
 | 
|  |    135 |          -- right
 | 
|  |    136 |          T := Wordops.Rotate(S_R(J),
 | 
|  |    137 |                              CRA +
 | 
|  |    138 |                                F(79 - J, CRB, CRC, CRD) +
 | 
|  |    139 |                                X(R_R(J)) +
 | 
|  |    140 |                                K_R(J)) +
 | 
|  |    141 |            CRE;
 | 
|  |    142 |          CRA := CRE;
 | 
|  |    143 |          CRE := CRD;
 | 
|  |    144 |          CRD := Wordops.Rotate(10, CRC);
 | 
|  |    145 |          CRC := CRB;
 | 
|  |    146 |          CRB := T;
 | 
|  |    147 |          --# assert Chain_Pair'(Chain'(CLA, CLB, CLC, CLD, CLE),
 | 
|  |    148 |          --#                    Chain'(CRA, CRB, CRC, CRD, CRE)) =
 | 
|  |    149 |          --#   steps(Chain_Pair'(Chain'(CA~, CB~, CC~, CD~, CE~),
 | 
|  |    150 |          --#                    Chain'(CA~, CB~, CC~, CD~, CE~)), J + 1, X)
 | 
|  |    151 |          --# and CA = CA~ and CB = CB~ and CC = CC~ and CD = CD~ and CE = CE~;
 | 
|  |    152 |       end loop;
 | 
|  |    153 |       T    := CB + CLC + CRD;
 | 
|  |    154 |       CB := CC + CLD + CRE;
 | 
|  |    155 |       CC := CD + CLE + CRA;
 | 
|  |    156 |       CD := CE + CLA + CRB;
 | 
|  |    157 |       CE := CA + CLB + CRC;
 | 
|  |    158 |       CA := T;
 | 
|  |    159 |    end Round;
 | 
|  |    160 | 
 | 
|  |    161 |    function Hash(X : Message) return Chain
 | 
|  |    162 |    is
 | 
|  |    163 |       CA_Init : constant Word := 16#6745_2301#;
 | 
|  |    164 |       CB_Init : constant Word := 16#EFCD_AB89#;
 | 
|  |    165 |       CC_Init : constant Word := 16#98BA_DCFE#;
 | 
|  |    166 |       CD_Init : constant Word := 16#1032_5476#;
 | 
|  |    167 |       CE_Init : constant Word := 16#C3D2_E1F0#;
 | 
|  |    168 |       CA, CB, CC, CD, CE : Word;
 | 
|  |    169 |    begin
 | 
|  |    170 |       CA := CA_Init;
 | 
|  |    171 |       CB := CB_Init;
 | 
|  |    172 |       CC := CC_Init;
 | 
|  |    173 |       CD := CD_Init;
 | 
|  |    174 |       CE := CE_Init;
 | 
|  |    175 |       for I in Message_Index range X'First..X'Last
 | 
|  |    176 |       loop
 | 
|  |    177 |          Round(CA, CB, CC, CD, CE, X(I));
 | 
|  |    178 |          --# assert Chain'(CA, CB, CC, CD, CE) = rounds(
 | 
|  |    179 |          --#    Chain'(CA_Init, CB_Init, CC_Init, CD_Init, CE_Init),
 | 
|  |    180 |          --#    I + 1,
 | 
|  |    181 |          --#    X);
 | 
|  |    182 |       end loop;
 | 
|  |    183 |       return Chain'(CA, CB, CC, CD, CE);
 | 
|  |    184 |    end Hash;
 | 
|  |    185 | 
 | 
|  |    186 | end RMD;
 | 
|  |    187 | 
 |