Botan  1.11.15
src/lib/hash/gost_3411/gost_3411.cpp
Go to the documentation of this file.
00001 /*
00002 * GOST 34.11
00003 * (C) 2009 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/hash_utils.h>
00009 #include <botan/gost_3411.h>
00010 #include <botan/internal/xor_buf.h>
00011 
00012 namespace Botan {
00013 
00014 BOTAN_REGISTER_HASH_NAMED_NOARGS(GOST_34_11, "GOST-R-34.11-94");
00015 
00016 /**
00017 * GOST 34.11 Constructor
00018 */
00019 GOST_34_11::GOST_34_11() :
00020    cipher(GOST_28147_89_Params("R3411_CryptoPro")),
00021    buffer(32),
00022    sum(32),
00023    hash(32)
00024    {
00025    count = 0;
00026    position = 0;
00027    }
00028 
00029 void GOST_34_11::clear()
00030    {
00031    cipher.clear();
00032    zeroise(sum);
00033    zeroise(hash);
00034    count = 0;
00035    position = 0;
00036    }
00037 
00038 /**
00039 * Hash additional inputs
00040 */
00041 void GOST_34_11::add_data(const byte input[], size_t length)
00042    {
00043    count += length;
00044 
00045    if(position)
00046       {
00047       buffer_insert(buffer, position, input, length);
00048 
00049       if(position + length >= hash_block_size())
00050          {
00051          compress_n(&buffer[0], 1);
00052          input += (hash_block_size() - position);
00053          length -= (hash_block_size() - position);
00054          position = 0;
00055          }
00056       }
00057 
00058    const size_t full_blocks = length / hash_block_size();
00059    const size_t remaining   = length % hash_block_size();
00060 
00061    if(full_blocks)
00062       compress_n(input, full_blocks);
00063 
00064    buffer_insert(buffer, position, input + full_blocks * hash_block_size(), remaining);
00065    position += remaining;
00066    }
00067 
00068 /**
00069 * The GOST 34.11 compression function
00070 */
00071 void GOST_34_11::compress_n(const byte input[], size_t blocks)
00072    {
00073    for(size_t i = 0; i != blocks; ++i)
00074       {
00075       for(u16bit j = 0, carry = 0; j != 32; ++j)
00076          {
00077          u16bit s = sum[j] + input[32*i+j] + carry;
00078          carry = get_byte(0, s);
00079          sum[j] = get_byte(1, s);
00080          }
00081 
00082       byte S[32] = { 0 };
00083 
00084       u64bit U[4], V[4];
00085       load_be(U, &hash[0], 4);
00086       load_be(V, input + 32*i, 4);
00087 
00088       for(size_t j = 0; j != 4; ++j)
00089          {
00090          byte key[32] = { 0 };
00091 
00092          // P transformation
00093          for(size_t k = 0; k != 4; ++k)
00094             for(size_t l = 0; l != 8; ++l)
00095                key[4*l+k] = get_byte(l, U[k]) ^ get_byte(l, V[k]);
00096 
00097          cipher.set_key(key, 32);
00098          cipher.encrypt(&hash[8*j], S + 8*j);
00099 
00100          if(j == 3)
00101             break;
00102 
00103          // A(x)
00104          u64bit A_U = U[0];
00105          U[0] = U[1];
00106          U[1] = U[2];
00107          U[2] = U[3];
00108          U[3] = U[0] ^ A_U;
00109 
00110          if(j == 1) // C_3
00111             {
00112             U[0] ^= 0x00FF00FF00FF00FF;
00113             U[1] ^= 0xFF00FF00FF00FF00;
00114             U[2] ^= 0x00FFFF00FF0000FF;
00115             U[3] ^= 0xFF000000FFFF00FF;
00116             }
00117 
00118          // A(A(x))
00119          u64bit AA_V_1 = V[0] ^ V[1];
00120          u64bit AA_V_2 = V[1] ^ V[2];
00121          V[0] = V[2];
00122          V[1] = V[3];
00123          V[2] = AA_V_1;
00124          V[3] = AA_V_2;
00125          }
00126 
00127       byte S2[32] = { 0 };
00128 
00129       // 12 rounds of psi
00130       S2[ 0] = S[24];
00131       S2[ 1] = S[25];
00132       S2[ 2] = S[26];
00133       S2[ 3] = S[27];
00134       S2[ 4] = S[28];
00135       S2[ 5] = S[29];
00136       S2[ 6] = S[30];
00137       S2[ 7] = S[31];
00138       S2[ 8] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[24] ^ S[30];
00139       S2[ 9] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[25] ^ S[31];
00140       S2[10] = S[ 0] ^ S[ 8] ^ S[24] ^ S[26] ^ S[30];
00141       S2[11] = S[ 1] ^ S[ 9] ^ S[25] ^ S[27] ^ S[31];
00142       S2[12] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[10] ^ S[24] ^ S[26] ^ S[28] ^ S[30];
00143       S2[13] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[11] ^ S[25] ^ S[27] ^ S[29] ^ S[31];
00144       S2[14] = S[ 0] ^ S[ 4] ^ S[ 8] ^ S[12] ^ S[24] ^ S[26] ^ S[28];
00145       S2[15] = S[ 1] ^ S[ 5] ^ S[ 9] ^ S[13] ^ S[25] ^ S[27] ^ S[29];
00146       S2[16] = S[ 2] ^ S[ 6] ^ S[10] ^ S[14] ^ S[26] ^ S[28] ^ S[30];
00147       S2[17] = S[ 3] ^ S[ 7] ^ S[11] ^ S[15] ^ S[27] ^ S[29] ^ S[31];
00148       S2[18] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[12] ^ S[16] ^ S[24] ^ S[28];
00149       S2[19] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[13] ^ S[17] ^ S[25] ^ S[29];
00150       S2[20] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[14] ^ S[18] ^ S[26] ^ S[30];
00151       S2[21] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[15] ^ S[19] ^ S[27] ^ S[31];
00152       S2[22] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[16] ^ S[20] ^ S[24] ^ S[28] ^ S[30];
00153       S2[23] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[17] ^ S[21] ^ S[25] ^ S[29] ^ S[31];
00154       S2[24] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[18] ^ S[22] ^ S[24] ^ S[26];
00155       S2[25] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[19] ^ S[23] ^ S[25] ^ S[27];
00156       S2[26] = S[ 2] ^ S[ 8] ^ S[14] ^ S[16] ^ S[20] ^ S[24] ^ S[26] ^ S[28];
00157       S2[27] = S[ 3] ^ S[ 9] ^ S[15] ^ S[17] ^ S[21] ^ S[25] ^ S[27] ^ S[29];
00158       S2[28] = S[ 4] ^ S[10] ^ S[16] ^ S[18] ^ S[22] ^ S[26] ^ S[28] ^ S[30];
00159       S2[29] = S[ 5] ^ S[11] ^ S[17] ^ S[19] ^ S[23] ^ S[27] ^ S[29] ^ S[31];
00160       S2[30] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[12] ^ S[18] ^ S[20] ^ S[28];
00161       S2[31] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[13] ^ S[19] ^ S[21] ^ S[29];
00162 
00163       xor_buf(S, S2, input + 32*i, 32);
00164 
00165       S2[0] = S[0] ^ S[2] ^ S[4] ^ S[6] ^ S[24] ^ S[30];
00166       S2[1] = S[1] ^ S[3] ^ S[5] ^ S[7] ^ S[25] ^ S[31];
00167 
00168       copy_mem(S, S+2, 30);
00169       S[30] = S2[0];
00170       S[31] = S2[1];
00171 
00172       xor_buf(S, &hash[0], 32);
00173 
00174       // 61 rounds of psi
00175       S2[ 0] = S[ 2] ^ S[ 6] ^ S[14] ^ S[20] ^ S[22] ^ S[26] ^ S[28] ^ S[30];
00176       S2[ 1] = S[ 3] ^ S[ 7] ^ S[15] ^ S[21] ^ S[23] ^ S[27] ^ S[29] ^ S[31];
00177       S2[ 2] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[16] ^ S[22] ^ S[28];
00178       S2[ 3] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[17] ^ S[23] ^ S[29];
00179       S2[ 4] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[18] ^ S[24] ^ S[30];
00180       S2[ 5] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[19] ^ S[25] ^ S[31];
00181       S2[ 6] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[20] ^ S[24] ^ S[26] ^ S[30];
00182       S2[ 7] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[21] ^ S[25] ^ S[27] ^ S[31];
00183       S2[ 8] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[22] ^ S[24] ^ S[26] ^ S[28] ^ S[30];
00184       S2[ 9] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[23] ^ S[25] ^ S[27] ^ S[29] ^ S[31];
00185       S2[10] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[14] ^ S[16] ^ S[26] ^ S[28];
00186       S2[11] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[15] ^ S[17] ^ S[27] ^ S[29];
00187       S2[12] = S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[16] ^ S[18] ^ S[28] ^ S[30];
00188       S2[13] = S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[17] ^ S[19] ^ S[29] ^ S[31];
00189       S2[14] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[12] ^ S[18] ^ S[20] ^ S[24];
00190       S2[15] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[13] ^ S[19] ^ S[21] ^ S[25];
00191       S2[16] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[12] ^ S[14] ^ S[20] ^ S[22] ^ S[26];
00192       S2[17] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[13] ^ S[15] ^ S[21] ^ S[23] ^ S[27];
00193       S2[18] = S[ 4] ^ S[ 6] ^ S[10] ^ S[12] ^ S[14] ^ S[16] ^ S[22] ^ S[24] ^ S[28];
00194       S2[19] = S[ 5] ^ S[ 7] ^ S[11] ^ S[13] ^ S[15] ^ S[17] ^ S[23] ^ S[25] ^ S[29];
00195       S2[20] = S[ 6] ^ S[ 8] ^ S[12] ^ S[14] ^ S[16] ^ S[18] ^ S[24] ^ S[26] ^ S[30];
00196       S2[21] = S[ 7] ^ S[ 9] ^ S[13] ^ S[15] ^ S[17] ^ S[19] ^ S[25] ^ S[27] ^ S[31];
00197       S2[22] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[14] ^ S[16] ^
00198                S[18] ^ S[20] ^ S[24] ^ S[26] ^ S[28] ^ S[30];
00199       S2[23] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[15] ^ S[17] ^
00200                S[19] ^ S[21] ^ S[25] ^ S[27] ^ S[29] ^ S[31];
00201       S2[24] = S[ 0] ^ S[ 8] ^ S[10] ^ S[12] ^ S[16] ^ S[18] ^ S[20] ^ S[22] ^
00202                S[24] ^ S[26] ^ S[28];
00203       S2[25] = S[ 1] ^ S[ 9] ^ S[11] ^ S[13] ^ S[17] ^ S[19] ^ S[21] ^ S[23] ^
00204                S[25] ^ S[27] ^ S[29];
00205       S2[26] = S[ 2] ^ S[10] ^ S[12] ^ S[14] ^ S[18] ^ S[20] ^ S[22] ^ S[24] ^
00206                S[26] ^ S[28] ^ S[30];
00207       S2[27] = S[ 3] ^ S[11] ^ S[13] ^ S[15] ^ S[19] ^ S[21] ^ S[23] ^ S[25] ^
00208                S[27] ^ S[29] ^ S[31];
00209       S2[28] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[12] ^ S[14] ^ S[16] ^ S[20] ^ S[22] ^ S[26] ^ S[28];
00210       S2[29] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[13] ^ S[15] ^ S[17] ^ S[21] ^ S[23] ^ S[27] ^ S[29];
00211       S2[30] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[14] ^ S[16] ^ S[18] ^ S[22] ^ S[24] ^ S[28] ^ S[30];
00212       S2[31] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[15] ^ S[17] ^ S[19] ^ S[23] ^ S[25] ^ S[29] ^ S[31];
00213 
00214       copy_mem(&hash[0], &S2[0], 32);
00215       }
00216    }
00217 
00218 /**
00219 * Produce the final GOST 34.11 output
00220 */
00221 void GOST_34_11::final_result(byte out[])
00222    {
00223    if(position)
00224       {
00225       clear_mem(&buffer[0] + position, buffer.size() - position);
00226       compress_n(&buffer[0], 1);
00227       }
00228 
00229    secure_vector<byte> length_buf(32);
00230    const u64bit bit_count = count * 8;
00231    store_le(bit_count, &length_buf[0]);
00232 
00233    secure_vector<byte> sum_buf = sum;
00234 
00235    compress_n(&length_buf[0], 1);
00236    compress_n(&sum_buf[0], 1);
00237 
00238    copy_mem(out, &hash[0], 32);
00239 
00240    clear();
00241    }
00242 
00243 }