~ubuntu-branches/ubuntu/trusty/rhash/trusty

« back to all changes in this revision

Viewing changes to librhash/gost.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexey S Kravchenko
  • Date: 2011-06-15 01:03:34 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110615010334-ochayini7ut2djvs
Tags: 1.2.6-1
* New upstream release version 1.2.6
 - ABI changed - now librhash0.0 is librhash0
 - OpenSSL support for faster hash calculation if libssl is installed
   (fully optional) for both rhash and librhash0

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * based on the Russian Standard GOST R 34.11-94.
3
3
 * See also RFC 4357.
4
4
 *
5
 
 * Implementation written by Alexei Kravchenko.
 
5
 * Copyright: 2009 Alexey Kravchenko <rhash.admin@gmail.com>
6
6
 *
7
 
 * Copyleft:
8
 
 * I hereby release this code into the public domain. This applies worldwide.
9
 
 * I grant any entity the right to use this work for ANY PURPOSE,
10
 
 * without any conditions, unless such conditions are required by law.
 
7
 * Permission is hereby granted,  free of charge,  to any person  obtaining a
 
8
 * copy of this software and associated documentation files (the "Software"),
 
9
 * to deal in the Software without restriction,  including without limitation
 
10
 * the rights to  use, copy, modify,  merge, publish, distribute, sublicense,
 
11
 * and/or sell copies  of  the Software,  and to permit  persons  to whom the
 
12
 * Software is furnished to do so.
11
13
 */
12
14
 
13
15
#include <string.h>
14
16
#include "byte_order.h"
15
17
#include "gost.h"
16
18
 
17
 
extern unsigned gost_sbox[4][256];
18
 
extern unsigned gost_sbox_cryptpro[4][256];
 
19
extern unsigned rhash_gost_sbox[4][256];
 
20
extern unsigned rhash_gost_sbox_cryptpro[4][256];
19
21
 
20
22
/**
21
23
 * Initialize algorithm context before calculaing hash
23
25
 *
24
26
 * @param ctx context to initalize
25
27
 */
26
 
void gost_init(gost_ctx *ctx)
 
28
void rhash_gost_init(gost_ctx *ctx)
27
29
{
28
 
  memset(ctx, 0, sizeof(gost_ctx));
 
30
        memset(ctx, 0, sizeof(gost_ctx));
29
31
}
30
32
 
31
33
/**
33
35
 *
34
36
 * @param ctx context to initalize
35
37
 */
36
 
void gost_cryptopro_init(gost_ctx *ctx)
 
38
void rhash_gost_cryptopro_init(gost_ctx *ctx)
37
39
{
38
 
  gost_init(ctx);
39
 
  ctx->cryptpro = 1;
 
40
        rhash_gost_init(ctx);
 
41
        ctx->cryptpro = 1;
40
42
}
41
43
 
42
44
#if defined(__GNUC__) && defined(CPU_IA32) && !defined(RHASH_NO_ASM)
52
54
 */
53
55
#ifndef USE_GCC_ASM_IA32
54
56
# define GOST_ENCRYPT_ROUND(key1, key2, sbox) \
55
 
  tmp = (key1) + r; \
56
 
  l ^= (sbox)[tmp & 0xff] ^ ((sbox)+256)[(tmp >> 8) & 0xff] ^ \
57
 
    ((sbox)+512)[(tmp >> 16) & 0xff] ^ ((sbox)+768)[tmp >> 24]; \
58
 
  tmp = (key2) + l; \
59
 
  r ^= (sbox)[tmp & 0xff] ^ ((sbox)+256)[(tmp >> 8) & 0xff] ^ \
60
 
    ((sbox)+512)[(tmp >> 16) & 0xff] ^ ((sbox)+768)[tmp >> 24];
 
57
        tmp = (key1) + r; \
 
58
        l ^= (sbox)[tmp & 0xff] ^ ((sbox)+256)[(tmp >> 8) & 0xff] ^ \
 
59
                ((sbox)+512)[(tmp >> 16) & 0xff] ^ ((sbox)+768)[tmp >> 24]; \
 
60
        tmp = (key2) + l; \
 
61
        r ^= (sbox)[tmp & 0xff] ^ ((sbox)+256)[(tmp >> 8) & 0xff] ^ \
 
62
                ((sbox)+512)[(tmp >> 16) & 0xff] ^ ((sbox)+768)[tmp >> 24];
61
63
 
62
64
/* encrypt a block with the given key */
63
65
# define GOST_ENCRYPT(result, i, key, hash, sbox) \
64
 
  r = hash[i], l = hash[i + 1]; \
65
 
  GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
66
 
  GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
67
 
  GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
68
 
  GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
69
 
  GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
70
 
  GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
71
 
  GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
72
 
  GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
73
 
  GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
74
 
  GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
75
 
  GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
76
 
  GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
77
 
  GOST_ENCRYPT_ROUND(key[7], key[6], sbox) \
78
 
  GOST_ENCRYPT_ROUND(key[5], key[4], sbox) \
79
 
  GOST_ENCRYPT_ROUND(key[3], key[2], sbox) \
80
 
  GOST_ENCRYPT_ROUND(key[1], key[0], sbox) \
81
 
  result[i] = l, result[i + 1] = r;
 
66
        r = hash[i], l = hash[i + 1]; \
 
67
        GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
 
68
        GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
 
69
        GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
 
70
        GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
 
71
        GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
 
72
        GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
 
73
        GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
 
74
        GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
 
75
        GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \
 
76
        GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \
 
77
        GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \
 
78
        GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \
 
79
        GOST_ENCRYPT_ROUND(key[7], key[6], sbox) \
 
80
        GOST_ENCRYPT_ROUND(key[5], key[4], sbox) \
 
81
        GOST_ENCRYPT_ROUND(key[3], key[2], sbox) \
 
82
        GOST_ENCRYPT_ROUND(key[1], key[0], sbox) \
 
83
        result[i] = l, result[i + 1] = r;
82
84
 
83
85
#else /* USE_GCC_ASM_IA32 */
84
86
 
85
87
/* a faster x86 version of GOST_ENCRYPT() */
86
88
/* it supposes edi=r, esi=l, edx=sbox ; */
87
89
# define ENC_ROUND_ASMx86(key, reg1, reg2) \
88
 
    "movl %" #key ", %%eax\n\t" \
89
 
    "addl %%" #reg1 ", %%eax\n\t" \
90
 
    "movzx %%al, %%ebx\n\t" \
91
 
    "movzx %%ah, %%ecx\n\t" \
92
 
    "xorl (%%edx, %%ebx, 4), %%" #reg2 "\n\t" \
93
 
    "xorl 1024(%%edx, %%ecx, 4), %%" #reg2 "\n\t" \
94
 
    "shrl $16, %%eax\n\t" \
95
 
    "movzx %%al, %%ebx\n\t" \
96
 
    "shrl $8, %%eax\n\t" \
97
 
    "xorl 2048(%%edx, %%ebx, 4), %%" #reg2 "\n\t" \
98
 
    "xorl 3072(%%edx, %%eax, 4), %%" #reg2 "\n\t"
 
90
        "movl %" #key ", %%eax\n\t" \
 
91
        "addl %%" #reg1 ", %%eax\n\t" \
 
92
        "movzx %%al, %%ebx\n\t" \
 
93
        "movzx %%ah, %%ecx\n\t" \
 
94
        "xorl (%%edx, %%ebx, 4), %%" #reg2 "\n\t" \
 
95
        "xorl 1024(%%edx, %%ecx, 4), %%" #reg2 "\n\t" \
 
96
        "shrl $16, %%eax\n\t" \
 
97
        "movzx %%al, %%ebx\n\t" \
 
98
        "shrl $8, %%eax\n\t" \
 
99
        "xorl 2048(%%edx, %%ebx, 4), %%" #reg2 "\n\t" \
 
100
        "xorl 3072(%%edx, %%eax, 4), %%" #reg2 "\n\t"
99
101
 
100
102
# define ENC_ASM(key1, key2) ENC_ROUND_ASMx86(key1, edi, esi) ENC_ROUND_ASMx86(key2, esi, edi)
101
103
# define GOST_ENCRYPT_GCC_ASM_X86() \
102
 
  ENC_ASM( 5,  6) ENC_ASM( 7,  8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
103
 
  ENC_ASM( 5,  6) ENC_ASM( 7,  8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
104
 
  ENC_ASM( 5,  6) ENC_ASM( 7,  8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
105
 
  ENC_ASM(12, 11) ENC_ASM(10,  9) ENC_ASM( 8,  7) ENC_ASM( 6,  5)
 
104
        ENC_ASM( 5,  6) ENC_ASM( 7,  8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
 
105
        ENC_ASM( 5,  6) ENC_ASM( 7,  8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
 
106
        ENC_ASM( 5,  6) ENC_ASM( 7,  8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
 
107
        ENC_ASM(12, 11) ENC_ASM(10,  9) ENC_ASM( 8,  7) ENC_ASM( 6,  5)
106
108
#endif /* USE_GCC_ASM_IA32 */
107
109
 
108
110
/**
111
113
 * @param hash intermediate message hash
112
114
 * @param block the message block to process
113
115
 */
114
 
static void gost_block_compress(gost_ctx *ctx, const unsigned* block)
 
116
static void rhash_gost_block_compress(gost_ctx *ctx, const unsigned* block)
115
117
{
116
 
  unsigned i;
117
 
  unsigned key[8], u[8], v[8], w[8], s[8];
118
 
  unsigned *sbox = (ctx->cryptpro ? (unsigned*)gost_sbox_cryptpro : (unsigned*)gost_sbox);
119
 
 
120
 
  /* u := hash, v := <256-bit message block> */
121
 
  memcpy(u, ctx->hash, sizeof(u));
122
 
  memcpy(v, block, sizeof(v));
123
 
 
124
 
  /* w := u xor v */
125
 
  w[0] = u[0] ^ v[0], w[1] = u[1] ^ v[1];
126
 
  w[2] = u[2] ^ v[2], w[3] = u[3] ^ v[3];
127
 
  w[4] = u[4] ^ v[4], w[5] = u[5] ^ v[5];
128
 
  w[6] = u[6] ^ v[6], w[7] = u[7] ^ v[7];
129
 
 
130
 
  /* calculate keys, encrypt hash and store result to the s[] array */
131
 
  for(i = 0;; i += 2) {
132
 
    /* key generation: key_i := P(w) */
133
 
    key[0] = (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24);
134
 
    key[1] = ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) | ((w[4] & 0x0000ff00) << 8)  | ((w[6] & 0x0000ff00) << 16);
135
 
    key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8);
136
 
    key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000);
137
 
    key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24);
138
 
    key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) | ((w[5] & 0x0000ff00) << 8)  | ((w[7] & 0x0000ff00) << 16);
139
 
    key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8);
140
 
    key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
141
 
 
142
 
    /* encryption: s_i := E_{key_i} (h_i) */
 
118
        unsigned i;
 
119
        unsigned key[8], u[8], v[8], w[8], s[8];
 
120
        unsigned *sbox = (ctx->cryptpro ? (unsigned*)rhash_gost_sbox_cryptpro : (unsigned*)rhash_gost_sbox);
 
121
 
 
122
        /* u := hash, v := <256-bit message block> */
 
123
        memcpy(u, ctx->hash, sizeof(u));
 
124
        memcpy(v, block, sizeof(v));
 
125
 
 
126
        /* w := u xor v */
 
127
        w[0] = u[0] ^ v[0], w[1] = u[1] ^ v[1];
 
128
        w[2] = u[2] ^ v[2], w[3] = u[3] ^ v[3];
 
129
        w[4] = u[4] ^ v[4], w[5] = u[5] ^ v[5];
 
130
        w[6] = u[6] ^ v[6], w[7] = u[7] ^ v[7];
 
131
 
 
132
        /* calculate keys, encrypt hash and store result to the s[] array */
 
133
        for(i = 0;; i += 2) {
 
134
                /* key generation: key_i := P(w) */
 
135
                key[0] = (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24);
 
136
                key[1] = ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) | ((w[4] & 0x0000ff00) << 8)  | ((w[6] & 0x0000ff00) << 16);
 
137
                key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8);
 
138
                key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000);
 
139
                key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24);
 
140
                key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) | ((w[5] & 0x0000ff00) << 8)  | ((w[7] & 0x0000ff00) << 16);
 
141
                key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8);
 
142
                key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
 
143
 
 
144
                /* encryption: s_i := E_{key_i} (h_i) */
143
145
#ifndef USE_GCC_ASM_IA32
144
 
    {
145
 
      unsigned l, r, tmp;
146
 
      GOST_ENCRYPT(s, i, key, ctx->hash, sbox);
147
 
    }
 
146
                {
 
147
                        unsigned l, r, tmp;
 
148
                        GOST_ENCRYPT(s, i, key, ctx->hash, sbox);
 
149
                }
148
150
#else /* USE_GCC_ASM_IA32 */
149
 
    __asm __volatile(
150
 
      "movl %%ebx, %13\n\t"
151
 
      GOST_ENCRYPT_GCC_ASM_X86() /* optimized for x86 Intel Core 2 */
152
 
      "movl %13, %%ebx\n\t"
153
 
      : "=S" (s[i]), "=D" (s[i+1]) /* 0,1: s[i]=esi, s[i+1]=edi */
154
 
      : "d" (sbox), "D" (ctx->hash[i]), "S" (ctx->hash[i+1]), /* 2,3,4: edx=sbox,edi=r,esi=l */
155
 
        "m" (key[0]), "m" (key[1]), "m" (key[2]), "m" (key[3]), /* 5, 6, 7, 8 */
156
 
        "m" (key[4]), "m" (key[5]), "m" (key[6]), "m" (key[7]), /* 9,10,11,12 */
157
 
        /* use w[0] to store ebx register, which is needed to be kept for PIC on *BSD */ 
158
 
        /* we avoid push/pop instructions incompatible with gcc -fomit-frame-pointer */
159
 
        "m" (w[0])
160
 
      : "cc", "eax", "ecx");
 
151
                __asm __volatile(
 
152
                        "movl %%ebx, %13\n\t"
 
153
                        GOST_ENCRYPT_GCC_ASM_X86() /* optimized for x86 Intel Core 2 */
 
154
                        "movl %13, %%ebx\n\t"
 
155
                        : "=S" (s[i]), "=D" (s[i+1]) /* 0,1: s[i]=esi, s[i+1]=edi */
 
156
                        : "d" (sbox), "D" (ctx->hash[i]), "S" (ctx->hash[i+1]), /* 2,3,4: edx=sbox,edi=r,esi=l */
 
157
                        "m" (key[0]), "m" (key[1]), "m" (key[2]), "m" (key[3]), /* 5, 6, 7, 8 */
 
158
                        "m" (key[4]), "m" (key[5]), "m" (key[6]), "m" (key[7]), /* 9,10,11,12 */
 
159
                        "m" (w[0])  /* store EBX in w[0], cause it's used for PIC on *BSD. */ 
 
160
                        /* We avoid push/pop instructions incompatible with gcc -fomit-frame-pointer */
 
161
                        : "cc", "eax", "ecx");
161
162
#endif /* USE_GCC_ASM_IA32 */
162
163
 
163
 
    if(i == 0) {
164
 
      /* w:= A(u) ^ A^2(v) */
165
 
      w[0] = u[2] ^ v[4], w[1] = u[3] ^ v[5];
166
 
      w[2] = u[4] ^ v[6], w[3] = u[5] ^ v[7];
167
 
      w[4] = u[6] ^ (v[0] ^= v[2]);
168
 
      w[5] = u[7] ^ (v[1] ^= v[3]);
169
 
      w[6] = (u[0] ^= u[2]) ^ (v[2] ^= v[4]);
170
 
      w[7] = (u[1] ^= u[3]) ^ (v[3] ^= v[5]);
171
 
    } else if((i & 2) != 0) {
172
 
      if(i == 6) break;
173
 
 
174
 
      /* w := A^2(u) xor A^4(v) xor C_3; u := A(u) xor C_3 */
175
 
      /* C_3=0xff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00 */
176
 
      u[2] ^= u[4] ^ 0x000000ff;
177
 
      u[3] ^= u[5] ^ 0xff00ffff;
178
 
      u[4] ^= 0xff00ff00;
179
 
      u[5] ^= 0xff00ff00;
180
 
      u[6] ^= 0x00ff00ff;
181
 
      u[7] ^= 0x00ff00ff;
182
 
      u[0] ^= 0x00ffff00;
183
 
      u[1] ^= 0xff0000ff;
184
 
 
185
 
      w[0] = u[4] ^ v[0];
186
 
      w[2] = u[6] ^ v[2];
187
 
      w[4] = u[0] ^ (v[4] ^= v[6]);
188
 
      w[6] = u[2] ^ (v[6] ^= v[0]);
189
 
      w[1] = u[5] ^ v[1];
190
 
      w[3] = u[7] ^ v[3];
191
 
      w[5] = u[1] ^ (v[5] ^= v[7]);
192
 
      w[7] = u[3] ^ (v[7] ^= v[1]);
193
 
    } else {
194
 
      /* i==4 here */
195
 
      /* w:= A( A^2(u) xor C_3 ) xor A^6(v) */
196
 
      w[0] = u[6] ^ v[4], w[1] = u[7] ^ v[5];
197
 
      w[2] = u[0] ^ v[6], w[3] = u[1] ^ v[7];
198
 
      w[4] = u[2] ^ (v[0] ^= v[2]);
199
 
      w[5] = u[3] ^ (v[1] ^= v[3]);
200
 
      w[6] = (u[4] ^= u[6]) ^ (v[2] ^= v[4]);
201
 
      w[7] = (u[5] ^= u[7]) ^ (v[3] ^= v[5]);
202
 
    }
203
 
  }
204
 
 
205
 
  /* step hash function: x(block, hash) := psi^61(hash xor psi(block xor psi^12(S))) */
206
 
 
207
 
  /* 12 rounds of the LFSR and xor in <message block> */
208
 
  u[0] = block[0] ^ s[6];
209
 
  u[1] = block[1] ^ s[7];
210
 
  u[2] = block[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[7] & 0xffff0000) ^ (s[7] >> 16);
211
 
  u[3] = block[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ (s[1] << 16) ^ (s[1] >> 16) ^
212
 
      (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
213
 
  u[4] = block[4] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^
214
 
      (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
215
 
  u[5] = block[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^
216
 
      (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16);
217
 
  u[6] = block[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16)
218
 
      ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16);
219
 
  u[7] = block[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^
220
 
      (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
221
 
 
222
 
  /* 1 round of the LFSR (a mixing transformation) and xor with <hash> */
223
 
  v[0] = ctx->hash[0] ^ (u[1] << 16) ^ (u[0] >> 16);
224
 
  v[1] = ctx->hash[1] ^ (u[2] << 16) ^ (u[1] >> 16);
225
 
  v[2] = ctx->hash[2] ^ (u[3] << 16) ^ (u[2] >> 16);
226
 
  v[3] = ctx->hash[3] ^ (u[4] << 16) ^ (u[3] >> 16);
227
 
  v[4] = ctx->hash[4] ^ (u[5] << 16) ^ (u[4] >> 16);
228
 
  v[5] = ctx->hash[5] ^ (u[6] << 16) ^ (u[5] >> 16);
229
 
  v[6] = ctx->hash[6] ^ (u[7] << 16) ^ (u[6] >> 16);
230
 
  v[7] = ctx->hash[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000) ^ (u[7] >> 16);
231
 
 
232
 
  /* 61 rounds of LFSR, mixing up hash */
233
 
  ctx->hash[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ 
234
 
            (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ 
235
 
            (v[3] >> 16) ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^ 
236
 
            (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff);
237
 
  ctx->hash[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ 
238
 
            (v[1] & 0xffff) ^ v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ 
239
 
            (v[4] >> 16) ^ (v[5] << 16) ^ (v[6] << 16) ^ v[6] ^ 
240
 
            (v[7] & 0xffff0000) ^ (v[7] >> 16);
241
 
  ctx->hash[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ 
242
 
            (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ 
243
 
             v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ 
244
 
            (v[7] & 0xffff) ^ (v[7] << 16) ^ (v[7] >> 16);
245
 
  ctx->hash[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ 
246
 
            (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^ 
247
 
            (v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ 
248
 
            (v[5] << 16) ^ (v[6] << 16) ^ (v[7] & 0xffff) ^ (v[7] >> 16);
249
 
  ctx->hash[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ 
250
 
            (v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ 
251
 
            (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16);
252
 
  ctx->hash[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ 
253
 
            (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ 
254
 
            (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ 
255
 
            (v[5] << 16) ^ (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ 
256
 
            (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000);
257
 
  ctx->hash[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ 
258
 
            (v[4] >> 16) ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ 
259
 
            (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7];
260
 
  ctx->hash[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ 
261
 
            (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ 
262
 
            (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
 
164
                if(i == 0) {
 
165
                        /* w:= A(u) ^ A^2(v) */
 
166
                        w[0] = u[2] ^ v[4], w[1] = u[3] ^ v[5];
 
167
                        w[2] = u[4] ^ v[6], w[3] = u[5] ^ v[7];
 
168
                        w[4] = u[6] ^ (v[0] ^= v[2]);
 
169
                        w[5] = u[7] ^ (v[1] ^= v[3]);
 
170
                        w[6] = (u[0] ^= u[2]) ^ (v[2] ^= v[4]);
 
171
                        w[7] = (u[1] ^= u[3]) ^ (v[3] ^= v[5]);
 
172
                } else if((i & 2) != 0) {
 
173
                        if(i == 6) break;
 
174
 
 
175
                        /* w := A^2(u) xor A^4(v) xor C_3; u := A(u) xor C_3 */
 
176
                        /* C_3=0xff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00 */
 
177
                        u[2] ^= u[4] ^ 0x000000ff;
 
178
                        u[3] ^= u[5] ^ 0xff00ffff;
 
179
                        u[4] ^= 0xff00ff00;
 
180
                        u[5] ^= 0xff00ff00;
 
181
                        u[6] ^= 0x00ff00ff;
 
182
                        u[7] ^= 0x00ff00ff;
 
183
                        u[0] ^= 0x00ffff00;
 
184
                        u[1] ^= 0xff0000ff;
 
185
 
 
186
                        w[0] = u[4] ^ v[0];
 
187
                        w[2] = u[6] ^ v[2];
 
188
                        w[4] = u[0] ^ (v[4] ^= v[6]);
 
189
                        w[6] = u[2] ^ (v[6] ^= v[0]);
 
190
                        w[1] = u[5] ^ v[1];
 
191
                        w[3] = u[7] ^ v[3];
 
192
                        w[5] = u[1] ^ (v[5] ^= v[7]);
 
193
                        w[7] = u[3] ^ (v[7] ^= v[1]);
 
194
                } else {
 
195
                        /* i==4 here */
 
196
                        /* w:= A( A^2(u) xor C_3 ) xor A^6(v) */
 
197
                        w[0] = u[6] ^ v[4], w[1] = u[7] ^ v[5];
 
198
                        w[2] = u[0] ^ v[6], w[3] = u[1] ^ v[7];
 
199
                        w[4] = u[2] ^ (v[0] ^= v[2]);
 
200
                        w[5] = u[3] ^ (v[1] ^= v[3]);
 
201
                        w[6] = (u[4] ^= u[6]) ^ (v[2] ^= v[4]);
 
202
                        w[7] = (u[5] ^= u[7]) ^ (v[3] ^= v[5]);
 
203
                }
 
204
        }
 
205
 
 
206
        /* step hash function: x(block, hash) := psi^61(hash xor psi(block xor psi^12(S))) */
 
207
 
 
208
        /* 12 rounds of the LFSR and xor in <message block> */
 
209
        u[0] = block[0] ^ s[6];
 
210
        u[1] = block[1] ^ s[7];
 
211
        u[2] = block[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[7] & 0xffff0000) ^ (s[7] >> 16);
 
212
        u[3] = block[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ (s[1] << 16) ^ (s[1] >> 16) ^
 
213
                (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
 
214
        u[4] = block[4] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^
 
215
                (s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
 
216
        u[5] = block[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^
 
217
                (s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16);
 
218
        u[6] = block[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16)
 
219
                ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16);
 
220
        u[7] = block[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^
 
221
                (s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
 
222
 
 
223
        /* 1 round of the LFSR (a mixing transformation) and xor with <hash> */
 
224
        v[0] = ctx->hash[0] ^ (u[1] << 16) ^ (u[0] >> 16);
 
225
        v[1] = ctx->hash[1] ^ (u[2] << 16) ^ (u[1] >> 16);
 
226
        v[2] = ctx->hash[2] ^ (u[3] << 16) ^ (u[2] >> 16);
 
227
        v[3] = ctx->hash[3] ^ (u[4] << 16) ^ (u[3] >> 16);
 
228
        v[4] = ctx->hash[4] ^ (u[5] << 16) ^ (u[4] >> 16);
 
229
        v[5] = ctx->hash[5] ^ (u[6] << 16) ^ (u[5] >> 16);
 
230
        v[6] = ctx->hash[6] ^ (u[7] << 16) ^ (u[6] >> 16);
 
231
        v[7] = ctx->hash[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000) ^ (u[7] >> 16);
 
232
 
 
233
        /* 61 rounds of LFSR, mixing up hash */
 
234
        ctx->hash[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^ 
 
235
                (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ 
 
236
                (v[3] >> 16) ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^ 
 
237
                (v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff);
 
238
        ctx->hash[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ 
 
239
                (v[1] & 0xffff) ^ v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^ 
 
240
                (v[4] >> 16) ^ (v[5] << 16) ^ (v[6] << 16) ^ v[6] ^ 
 
241
                (v[7] & 0xffff0000) ^ (v[7] >> 16);
 
242
        ctx->hash[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^ 
 
243
                (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^ 
 
244
                v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^ 
 
245
                (v[7] & 0xffff) ^ (v[7] << 16) ^ (v[7] >> 16);
 
246
        ctx->hash[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^ 
 
247
                (v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^ 
 
248
                (v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^ 
 
249
                (v[5] << 16) ^ (v[6] << 16) ^ (v[7] & 0xffff) ^ (v[7] >> 16);
 
250
        ctx->hash[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^ 
 
251
                (v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ 
 
252
                (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16);
 
253
        ctx->hash[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^ 
 
254
                (v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^ 
 
255
                (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^ 
 
256
                (v[5] << 16) ^ (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ 
 
257
                (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000);
 
258
        ctx->hash[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^ 
 
259
                (v[4] >> 16) ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^ 
 
260
                (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7];
 
261
        ctx->hash[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^ 
 
262
                (v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^ 
 
263
                (v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
263
264
}
264
265
 
265
266
/**
267
268
 * It updates 256-bit check sum as follows:
268
269
 *    *(uint256_t)(ctx->sum) += *(uint256_t*)block;
269
270
 * and then updates intermediate hash value ctx->hash 
270
 
 * by calling gost_block_compress().
 
271
 * by calling rhash_gost_block_compress().
271
272
 *
272
273
 * @param ctx algorithm context
273
274
 * @param block the 256-bit message block to process
274
275
 */
275
 
static void gost_compute_sum_and_hash(gost_ctx * ctx, const unsigned* block)
 
276
static void rhash_gost_compute_sum_and_hash(gost_ctx * ctx, const unsigned* block)
276
277
{
277
278
#ifdef CPU_BIG_ENDIAN
278
 
  unsigned block_le[8]; /* tmp buffer for little endian number */
 
279
        unsigned block_le[8]; /* tmp buffer for little endian number */
279
280
# define LOAD_BLOCK_LE(i) (block_le[i] = le2me_32(block[i]))
280
281
#else
281
282
# define block_le block
282
283
# define LOAD_BLOCK_LE(i)
283
284
#endif
284
285
 
285
 
  /* This optimization doesn't improve speed much,
286
 
   * and saves too little memory, but it was fun to write! =)  */
 
286
        /* This optimization doesn't improve speed much,
 
287
        * and saves too little memory, but it was fun to write! =)  */
287
288
#ifdef USE_GCC_ASM_IA32
288
 
  __asm __volatile(
289
 
    "addl %0, (%1)\n\t"
290
 
    "movl 4(%2), %0\n\t"
291
 
    "adcl %0, 4(%1)\n\t"
292
 
    "movl 8(%2), %0\n\t"
293
 
    "adcl %0, 8(%1)\n\t"
294
 
    "movl 12(%2), %0\n\t"
295
 
    "adcl %0, 12(%1)\n\t"
296
 
    "movl 16(%2), %0\n\t"
297
 
    "adcl %0, 16(%1)\n\t"
298
 
    "movl 20(%2), %0\n\t"
299
 
    "adcl %0, 20(%1)\n\t"
300
 
    "movl 24(%2), %0\n\t"
301
 
    "adcl %0, 24(%1)\n\t"
302
 
    "movl 28(%2), %0\n\t"
303
 
    "adcl %0, 28(%1)\n\t"
304
 
    : : "r" (block[0]), "r" (ctx->sum), "r" (block)
305
 
    : "0", "memory", "cc"
306
 
  );
 
289
        __asm __volatile(
 
290
                "addl %0, (%1)\n\t"
 
291
                "movl 4(%2), %0\n\t"
 
292
                "adcl %0, 4(%1)\n\t"
 
293
                "movl 8(%2), %0\n\t"
 
294
                "adcl %0, 8(%1)\n\t"
 
295
                "movl 12(%2), %0\n\t"
 
296
                "adcl %0, 12(%1)\n\t"
 
297
                "movl 16(%2), %0\n\t"
 
298
                "adcl %0, 16(%1)\n\t"
 
299
                "movl 20(%2), %0\n\t"
 
300
                "adcl %0, 20(%1)\n\t"
 
301
                "movl 24(%2), %0\n\t"
 
302
                "adcl %0, 24(%1)\n\t"
 
303
                "movl 28(%2), %0\n\t"
 
304
                "adcl %0, 28(%1)\n\t"
 
305
                : : "r" (block[0]), "r" (ctx->sum), "r" (block)
 
306
                : "0", "memory", "cc" );
307
307
#elif defined(USE_GCC_ASM_X64)
308
 
  const uint64_t* block64 = (const uint64_t*)block;
309
 
  uint64_t* sum64 = (uint64_t*)ctx->sum;
310
 
  __asm __volatile(
311
 
    "addq %4, %0\n\t"
312
 
    "adcq %5, %1\n\t"
313
 
    "adcq %6, %2\n\t"
314
 
    "adcq %7, %3\n\t"
315
 
    : "+mr" (sum64[0]), "+mr" (sum64[1]), "+mr" (sum64[2]), "+mr" (sum64[3])
316
 
    : "r" (block64[0]), "r" (block64[1]), "r" (block64[2]), "r" (block64[3])
317
 
    : "cc"
318
 
  );
 
308
        const uint64_t* block64 = (const uint64_t*)block;
 
309
        uint64_t* sum64 = (uint64_t*)ctx->sum;
 
310
        __asm __volatile(
 
311
                "addq %4, %0\n\t"
 
312
                "adcq %5, %1\n\t"
 
313
                "adcq %6, %2\n\t"
 
314
                "adcq %7, %3\n\t"
 
315
                : "+m" (sum64[0]), "+m" (sum64[1]), "+m" (sum64[2]), "+m" (sum64[3])
 
316
                : "r" (block64[0]), "r" (block64[1]), "r" (block64[2]), "r" (block64[3])
 
317
                : "cc" );
319
318
#else /* USE_GCC_ASM_IA32 */
320
319
 
321
 
  unsigned i, carry = 0;
 
320
        unsigned i, carry = 0;
322
321
 
323
 
  /* compute the 256-bit sum */
324
 
  for(i = 0; i < 8; i++) {
325
 
    const unsigned old = ctx->sum[i];
326
 
    LOAD_BLOCK_LE(i);
327
 
    ctx->sum[i] += block_le[i] + carry;
328
 
    carry = (ctx->sum[i] < old || ctx->sum[i] < block_le[i] ? 1 : 0);
329
 
  }
 
322
        /* compute the 256-bit sum */
 
323
        for(i = 0; i < 8; i++) {
 
324
                const unsigned old = ctx->sum[i];
 
325
                LOAD_BLOCK_LE(i);
 
326
                ctx->sum[i] += block_le[i] + carry;
 
327
                carry = (ctx->sum[i] < old || ctx->sum[i] < block_le[i] ? 1 : 0);
 
328
        }
330
329
#endif /* USE_GCC_ASM_IA32 */
331
330
 
332
 
  /* update message hash */
333
 
  gost_block_compress(ctx, block_le);
 
331
        /* update message hash */
 
332
        rhash_gost_block_compress(ctx, block_le);
334
333
}
335
334
 
336
335
/**
341
340
 * @param msg message chunk
342
341
 * @param size length of the message chunk
343
342
 */
344
 
void gost_update(gost_ctx *ctx, const unsigned char* msg, size_t size)
 
343
void rhash_gost_update(gost_ctx *ctx, const unsigned char* msg, size_t size)
345
344
{
346
 
  unsigned index = (unsigned)ctx->length & 31;
347
 
  ctx->length += size;
348
 
  
349
 
  /* fill partial block */
350
 
  if(index) {
351
 
    unsigned left = gost_block_size - index;
352
 
    memcpy(ctx->message + index, msg, (size < left ? size : left));
353
 
    if(size < left) return;
354
 
 
355
 
    /* process partial block */
356
 
    gost_compute_sum_and_hash(ctx, (unsigned*)ctx->message);
357
 
    msg += left;
358
 
    size -= left;
359
 
  }
360
 
  while(size >= gost_block_size) {
361
 
    unsigned* aligned_message_block;
 
345
        unsigned index = (unsigned)ctx->length & 31;
 
346
        ctx->length += size;
 
347
 
 
348
        /* fill partial block */
 
349
        if(index) {
 
350
                unsigned left = gost_block_size - index;
 
351
                memcpy(ctx->message + index, msg, (size < left ? size : left));
 
352
                if(size < left) return;
 
353
 
 
354
                /* process partial block */
 
355
                rhash_gost_compute_sum_and_hash(ctx, (unsigned*)ctx->message);
 
356
                msg += left;
 
357
                size -= left;
 
358
        }
 
359
        while(size >= gost_block_size) {
 
360
                unsigned* aligned_message_block;
362
361
#if (defined(__GNUC__) && defined(CPU_X64))
363
 
    if( IS_ALIGNED_64(msg) ) {
 
362
                if(IS_ALIGNED_64(msg)) {
364
363
#else
365
 
    if( IS_ALIGNED_32(msg) ) {
 
364
                if(IS_ALIGNED_32(msg)) {
366
365
#endif
367
 
      /* the most common case is processing of an already aligned message 
368
 
         on little-endian CPU without copying it */
369
 
      aligned_message_block = (unsigned*)msg;
370
 
    } else {
371
 
      memcpy(ctx->message, msg, gost_block_size);
372
 
      aligned_message_block = (unsigned*)ctx->message;
373
 
    }
 
366
                        /* the most common case is processing of an already aligned message 
 
367
                        on little-endian CPU without copying it */
 
368
                        aligned_message_block = (unsigned*)msg;
 
369
                } else {
 
370
                        memcpy(ctx->message, msg, gost_block_size);
 
371
                        aligned_message_block = (unsigned*)ctx->message;
 
372
                }
374
373
 
375
 
    gost_compute_sum_and_hash(ctx, aligned_message_block);
376
 
    msg += gost_block_size;
377
 
    size -= gost_block_size;
378
 
  }
379
 
  if(size) {
380
 
    /* save leftovers */
381
 
    memcpy(ctx->message, msg, size);
382
 
  }
 
374
                rhash_gost_compute_sum_and_hash(ctx, aligned_message_block);
 
375
                msg += gost_block_size;
 
376
                size -= gost_block_size;
 
377
        }
 
378
        if(size) {
 
379
                /* save leftovers */
 
380
                memcpy(ctx->message, msg, size);
 
381
        }
383
382
}
384
383
 
385
384
/**
388
387
 * @param ctx the algorithm context containing current hashing state
389
388
 * @param result calculated hash in binary form
390
389
 */
391
 
void gost_final(gost_ctx *ctx, unsigned char result[32])
 
390
void rhash_gost_final(gost_ctx *ctx, unsigned char result[32])
392
391
{
393
 
  unsigned  index = (unsigned)ctx->length & 31;
394
 
  unsigned* msg32 = (unsigned*)ctx->message;
395
 
 
396
 
  /* pad the last block with zeroes and hash it */
397
 
  if(index > 0) {
398
 
    memset(ctx->message + index, 0, 32 - index);
399
 
    gost_compute_sum_and_hash(ctx, msg32);
400
 
  }
401
 
 
402
 
  /* hash the message length and the sum */
403
 
  msg32[0] = (unsigned)(ctx->length << 3);
404
 
  msg32[1] = (unsigned)(ctx->length >> 29);
405
 
  memset(msg32 + 2, 0, sizeof(unsigned)*6);
406
 
 
407
 
  gost_block_compress(ctx, msg32);
408
 
  gost_block_compress(ctx, ctx->sum);
409
 
 
410
 
  /* convert hash state to result bytes */
411
 
  le32_copy(result, ctx->hash, gost_hash_length);
 
392
        unsigned  index = (unsigned)ctx->length & 31;
 
393
        unsigned* msg32 = (unsigned*)ctx->message;
 
394
 
 
395
        /* pad the last block with zeroes and hash it */
 
396
        if(index > 0) {
 
397
                memset(ctx->message + index, 0, 32 - index);
 
398
                rhash_gost_compute_sum_and_hash(ctx, msg32);
 
399
        }
 
400
 
 
401
        /* hash the message length and the sum */
 
402
        msg32[0] = (unsigned)(ctx->length << 3);
 
403
        msg32[1] = (unsigned)(ctx->length >> 29);
 
404
        memset(msg32 + 2, 0, sizeof(unsigned)*6);
 
405
 
 
406
        rhash_gost_block_compress(ctx, msg32);
 
407
        rhash_gost_block_compress(ctx, ctx->sum);
 
408
 
 
409
        /* convert hash state to result bytes */
 
410
        le32_copy(result, 0, ctx->hash, gost_hash_length);
412
411
}
413
412
 
414
413
#ifdef GENERATE_GOST_LOOKUP_TABLE
415
 
unsigned gost_sbox[4][256];
416
 
unsigned gost_sbox_cryptpro[4][256];
 
414
unsigned rhash_gost_sbox[4][256];
 
415
unsigned rhash_gost_sbox_cryptpro[4][256];
417
416
 
418
417
/**
419
418
 * Calculate a lookup table from S-Boxes.
422
421
 * @param out pointer to the lookup table to fill
423
422
 * @param src pointer to eight S-Boxes to fill the table from
424
423
 */
425
 
static void fill_gost_sbox(unsigned out[4][256], const unsigned char src[8][16])
 
424
static void rhash_gost_fill_sbox(unsigned out[4][256], const unsigned char src[8][16])
426
425
{
427
 
  int a, b, i;
428
 
  unsigned long ax, bx, cx, dx;
429
 
 
430
 
  for(i = 0, a = 0; a < 16; a++) {
431
 
    ax = (unsigned)src[1][a] << 15;
432
 
    bx = (unsigned)src[3][a] << 23;
433
 
    cx = ROTL32((unsigned)src[5][a], 31);
434
 
    dx = (unsigned)src[7][a] << 7;
435
 
      
436
 
    for(b = 0; b < 16; b++, i++) {
437
 
      out[0][i] = ax | ((unsigned)src[0][b] << 11);
438
 
      out[1][i] = bx | ((unsigned)src[2][b] << 19);
439
 
      out[2][i] = cx | ((unsigned)src[4][b] << 27);
440
 
      out[3][i] = dx | ((unsigned)src[6][b] << 3);
441
 
    }
442
 
  }
 
426
        int a, b, i;
 
427
        unsigned long ax, bx, cx, dx;
 
428
 
 
429
        for(i = 0, a = 0; a < 16; a++) {
 
430
                ax = (unsigned)src[1][a] << 15;
 
431
                bx = (unsigned)src[3][a] << 23;
 
432
                cx = ROTL32((unsigned)src[5][a], 31);
 
433
                dx = (unsigned)src[7][a] << 7;
 
434
 
 
435
                for(b = 0; b < 16; b++, i++) {
 
436
                        out[0][i] = ax | ((unsigned)src[0][b] << 11);
 
437
                        out[1][i] = bx | ((unsigned)src[2][b] << 19);
 
438
                        out[2][i] = cx | ((unsigned)src[4][b] << 27);
 
439
                        out[3][i] = dx | ((unsigned)src[6][b] << 3);
 
440
                }
 
441
        }
443
442
}
444
443
 
445
444
/**
448
447
 * them at rine-time can save a little space in the exutable file
449
448
 * in trade of consuming some time at pogram start.
450
449
 */
451
 
void gost_init_table(void)
 
450
void rhash_gost_init_table(void)
452
451
{
453
 
  /* Test parameters set. Eight 4-bit S-Boxes defined by GOST R 34.10-94
454
 
   * standart for testing the hash function. 
455
 
   * Also given by RFC 4357 section 11.2 */
456
 
  static const unsigned char sbox[8][16] = {
457
 
    {  4, 10,  9,  2, 13,  8,  0, 14,  6, 11,  1, 12,  7, 15,  5,  3 },
458
 
    { 14, 11,  4, 12,  6, 13, 15, 10,  2,  3,  8,  1,  0,  7,  5,  9 },
459
 
    {  5,  8,  1, 13, 10,  3,  4,  2, 14, 15, 12,  7,  6,  0,  9, 11 },
460
 
    {  7, 13, 10,  1,  0,  8,  9, 15, 14,  4,  6, 12, 11,  2,  5,  3 },
461
 
    {  6, 12,  7,  1,  5, 15, 13,  8,  4, 10,  9, 14,  0,  3, 11,  2 },
462
 
    {  4, 11, 10,  0,  7,  2,  1, 13,  3,  6,  8,  5,  9, 12, 15, 14 },
463
 
    { 13, 11,  4,  1,  3, 15,  5,  9,  0, 10, 14,  7,  6,  8,  2, 12 },
464
 
    {  1, 15, 13,  0,  5,  7, 10,  4,  9,  2,  3, 14,  6, 11,  8, 12 }  
465
 
  };
466
 
 
467
 
  /* Parameter set recommended by RFC 4357.
468
 
   * Eight 4-bit S-Boxes as defined by RFC 4357 section 11.2 */
469
 
  static const unsigned char sbox_cryptpro[8][16] = {
470
 
    { 10,  4,  5,  6,  8,  1,  3,  7, 13, 12, 14,  0,  9,  2, 11, 15 },
471
 
    {  5, 15,  4,  0,  2, 13, 11,  9,  1,  7,  6,  3, 12, 14, 10,  8 },
472
 
    {  7, 15, 12, 14,  9,  4,  1,  0,  3, 11,  5,  2,  6, 10,  8, 13 },
473
 
    {  4, 10,  7, 12,  0, 15,  2,  8, 14,  1,  6,  5, 13, 11,  9,  3 },
474
 
    {  7,  6,  4, 11,  9, 12,  2, 10,  1,  8,  0, 14, 15, 13,  3,  5 },
475
 
    {  7,  6,  2,  4, 13,  9, 15,  0, 10,  1,  5, 11,  8, 14, 12,  3 },
476
 
    { 13, 14,  4,  1,  7,  0,  5, 10,  3, 12,  8, 15,  6,  2,  9, 11 },
477
 
    {  1,  3, 10,  9,  5, 11,  4, 15,  8,  6,  7, 14, 13,  0,  2, 12 }
478
 
  };
479
 
 
480
 
  fill_gost_sbox(gost_sbox, sbox);
481
 
  fill_gost_sbox(gost_sbox_cryptpro, sbox_cryptpro);
 
452
        /* Test parameters set. Eight 4-bit S-Boxes defined by GOST R 34.10-94
 
453
         * standart for testing the hash function. 
 
454
         * Also given by RFC 4357 section 11.2 */
 
455
        static const unsigned char sbox[8][16] = {
 
456
                {  4, 10,  9,  2, 13,  8,  0, 14,  6, 11,  1, 12,  7, 15,  5,  3 },
 
457
                { 14, 11,  4, 12,  6, 13, 15, 10,  2,  3,  8,  1,  0,  7,  5,  9 },
 
458
                {  5,  8,  1, 13, 10,  3,  4,  2, 14, 15, 12,  7,  6,  0,  9, 11 },
 
459
                {  7, 13, 10,  1,  0,  8,  9, 15, 14,  4,  6, 12, 11,  2,  5,  3 },
 
460
                {  6, 12,  7,  1,  5, 15, 13,  8,  4, 10,  9, 14,  0,  3, 11,  2 },
 
461
                {  4, 11, 10,  0,  7,  2,  1, 13,  3,  6,  8,  5,  9, 12, 15, 14 },
 
462
                { 13, 11,  4,  1,  3, 15,  5,  9,  0, 10, 14,  7,  6,  8,  2, 12 },
 
463
                {  1, 15, 13,  0,  5,  7, 10,  4,  9,  2,  3, 14,  6, 11,  8, 12 }  
 
464
        };
 
465
 
 
466
        /* Parameter set recommended by RFC 4357.
 
467
         * Eight 4-bit S-Boxes as defined by RFC 4357 section 11.2 */
 
468
        static const unsigned char sbox_cryptpro[8][16] = {
 
469
                { 10,  4,  5,  6,  8,  1,  3,  7, 13, 12, 14,  0,  9,  2, 11, 15 },
 
470
                {  5, 15,  4,  0,  2, 13, 11,  9,  1,  7,  6,  3, 12, 14, 10,  8 },
 
471
                {  7, 15, 12, 14,  9,  4,  1,  0,  3, 11,  5,  2,  6, 10,  8, 13 },
 
472
                {  4, 10,  7, 12,  0, 15,  2,  8, 14,  1,  6,  5, 13, 11,  9,  3 },
 
473
                {  7,  6,  4, 11,  9, 12,  2, 10,  1,  8,  0, 14, 15, 13,  3,  5 },
 
474
                {  7,  6,  2,  4, 13,  9, 15,  0, 10,  1,  5, 11,  8, 14, 12,  3 },
 
475
                { 13, 14,  4,  1,  7,  0,  5, 10,  3, 12,  8, 15,  6,  2,  9, 11 },
 
476
                {  1,  3, 10,  9,  5, 11,  4, 15,  8,  6,  7, 14, 13,  0,  2, 12 }
 
477
        };
 
478
 
 
479
        rhash_gost_fill_sbox(rhash_gost_sbox, sbox);
 
480
        rhash_gost_fill_sbox(rhash_gost_sbox_cryptpro, sbox_cryptpro);
482
481
}
483
482
 
484
483
#else /* GENERATE_GOST_LOOKUP_TABLE */
485
484
 
486
485
/* pre-initialized GOST lookup tables based on rotated S-Box */
487
 
unsigned gost_sbox[4][256] = {
488
 
  {
489
 
    0x72000, 0x75000, 0x74800, 0x71000, 0x76800,
490
 
    0x74000, 0x70000, 0x77000, 0x73000, 0x75800,
491
 
    0x70800, 0x76000, 0x73800, 0x77800, 0x72800,
492
 
    0x71800, 0x5A000, 0x5D000, 0x5C800, 0x59000,
493
 
    0x5E800, 0x5C000, 0x58000, 0x5F000, 0x5B000,
494
 
    0x5D800, 0x58800, 0x5E000, 0x5B800, 0x5F800,
495
 
    0x5A800, 0x59800, 0x22000, 0x25000, 0x24800,
496
 
    0x21000, 0x26800, 0x24000, 0x20000, 0x27000,
497
 
    0x23000, 0x25800, 0x20800, 0x26000, 0x23800,
498
 
    0x27800, 0x22800, 0x21800, 0x62000, 0x65000,
499
 
    0x64800, 0x61000, 0x66800, 0x64000, 0x60000,
500
 
    0x67000, 0x63000, 0x65800, 0x60800, 0x66000,
501
 
    0x63800, 0x67800, 0x62800, 0x61800, 0x32000,
502
 
    0x35000, 0x34800, 0x31000, 0x36800, 0x34000,
503
 
    0x30000, 0x37000, 0x33000, 0x35800, 0x30800,
504
 
    0x36000, 0x33800, 0x37800, 0x32800, 0x31800,
505
 
    0x6A000, 0x6D000, 0x6C800, 0x69000, 0x6E800,
506
 
    0x6C000, 0x68000, 0x6F000, 0x6B000, 0x6D800,
507
 
    0x68800, 0x6E000, 0x6B800, 0x6F800, 0x6A800,
508
 
    0x69800, 0x7A000, 0x7D000, 0x7C800, 0x79000,
509
 
    0x7E800, 0x7C000, 0x78000, 0x7F000, 0x7B000,
510
 
    0x7D800, 0x78800, 0x7E000, 0x7B800, 0x7F800,
511
 
    0x7A800, 0x79800, 0x52000, 0x55000, 0x54800,
512
 
    0x51000, 0x56800, 0x54000, 0x50000, 0x57000,
513
 
    0x53000, 0x55800, 0x50800, 0x56000, 0x53800,
514
 
    0x57800, 0x52800, 0x51800, 0x12000, 0x15000,
515
 
    0x14800, 0x11000, 0x16800, 0x14000, 0x10000,
516
 
    0x17000, 0x13000, 0x15800, 0x10800, 0x16000,
517
 
    0x13800, 0x17800, 0x12800, 0x11800, 0x1A000,
518
 
    0x1D000, 0x1C800, 0x19000, 0x1E800, 0x1C000,
519
 
    0x18000, 0x1F000, 0x1B000, 0x1D800, 0x18800,
520
 
    0x1E000, 0x1B800, 0x1F800, 0x1A800, 0x19800,
521
 
    0x42000, 0x45000, 0x44800, 0x41000, 0x46800,
522
 
    0x44000, 0x40000, 0x47000, 0x43000, 0x45800,
523
 
    0x40800, 0x46000, 0x43800, 0x47800, 0x42800,
524
 
    0x41800, 0xA000,  0xD000,  0xC800,  0x9000,
525
 
    0xE800,  0xC000,  0x8000,  0xF000,  0xB000,
526
 
    0xD800,  0x8800,  0xE000,  0xB800,  0xF800,
527
 
    0xA800,  0x9800,  0x2000,  0x5000,  0x4800,
528
 
    0x1000,  0x6800,  0x4000,  0x0,     0x7000,
529
 
    0x3000,  0x5800,  0x800,   0x6000,  0x3800,
530
 
    0x7800,  0x2800,  0x1800,  0x3A000, 0x3D000,
531
 
    0x3C800, 0x39000, 0x3E800, 0x3C000, 0x38000,
532
 
    0x3F000, 0x3B000, 0x3D800, 0x38800, 0x3E000,
533
 
    0x3B800, 0x3F800, 0x3A800, 0x39800, 0x2A000,
534
 
    0x2D000, 0x2C800, 0x29000, 0x2E800, 0x2C000,
535
 
    0x28000, 0x2F000, 0x2B000, 0x2D800, 0x28800,
536
 
    0x2E000, 0x2B800, 0x2F800, 0x2A800, 0x29800,
537
 
    0x4A000, 0x4D000, 0x4C800, 0x49000, 0x4E800,
538
 
    0x4C000, 0x48000, 0x4F000, 0x4B000, 0x4D800,
539
 
    0x48800, 0x4E000, 0x4B800, 0x4F800, 0x4A800,
540
 
    0x49800
541
 
  }, {
542
 
    0x3A80000, 0x3C00000, 0x3880000, 0x3E80000, 0x3D00000,
543
 
    0x3980000, 0x3A00000, 0x3900000, 0x3F00000, 0x3F80000,
544
 
    0x3E00000, 0x3B80000, 0x3B00000, 0x3800000, 0x3C80000,
545
 
    0x3D80000, 0x6A80000, 0x6C00000, 0x6880000, 0x6E80000,
546
 
    0x6D00000, 0x6980000, 0x6A00000, 0x6900000, 0x6F00000,
547
 
    0x6F80000, 0x6E00000, 0x6B80000, 0x6B00000, 0x6800000,
548
 
    0x6C80000, 0x6D80000, 0x5280000, 0x5400000, 0x5080000,
549
 
    0x5680000, 0x5500000, 0x5180000, 0x5200000, 0x5100000,
550
 
    0x5700000, 0x5780000, 0x5600000, 0x5380000, 0x5300000,
551
 
    0x5000000, 0x5480000, 0x5580000, 0xA80000,  0xC00000,
552
 
    0x880000,  0xE80000,  0xD00000,  0x980000,  0xA00000,
553
 
    0x900000,  0xF00000,  0xF80000,  0xE00000,  0xB80000,
554
 
    0xB00000,  0x800000,  0xC80000,  0xD80000,  0x280000,
555
 
    0x400000,  0x80000,   0x680000,  0x500000,  0x180000,
556
 
    0x200000,  0x100000,  0x700000,  0x780000,  0x600000,
557
 
    0x380000,  0x300000,  0x0,       0x480000,  0x580000,
558
 
    0x4280000, 0x4400000, 0x4080000, 0x4680000, 0x4500000,
559
 
    0x4180000, 0x4200000, 0x4100000, 0x4700000, 0x4780000,
560
 
    0x4600000, 0x4380000, 0x4300000, 0x4000000, 0x4480000,
561
 
    0x4580000, 0x4A80000, 0x4C00000, 0x4880000, 0x4E80000,
562
 
    0x4D00000, 0x4980000, 0x4A00000, 0x4900000, 0x4F00000,
563
 
    0x4F80000, 0x4E00000, 0x4B80000, 0x4B00000, 0x4800000,
564
 
    0x4C80000, 0x4D80000, 0x7A80000, 0x7C00000, 0x7880000,
565
 
    0x7E80000, 0x7D00000, 0x7980000, 0x7A00000, 0x7900000,
566
 
    0x7F00000, 0x7F80000, 0x7E00000, 0x7B80000, 0x7B00000,
567
 
    0x7800000, 0x7C80000, 0x7D80000, 0x7280000, 0x7400000,
568
 
    0x7080000, 0x7680000, 0x7500000, 0x7180000, 0x7200000,
569
 
    0x7100000, 0x7700000, 0x7780000, 0x7600000, 0x7380000,
570
 
    0x7300000, 0x7000000, 0x7480000, 0x7580000, 0x2280000,
571
 
    0x2400000, 0x2080000, 0x2680000, 0x2500000, 0x2180000,
572
 
    0x2200000, 0x2100000, 0x2700000, 0x2780000, 0x2600000,
573
 
    0x2380000, 0x2300000, 0x2000000, 0x2480000, 0x2580000,
574
 
    0x3280000, 0x3400000, 0x3080000, 0x3680000, 0x3500000,
575
 
    0x3180000, 0x3200000, 0x3100000, 0x3700000, 0x3780000,
576
 
    0x3600000, 0x3380000, 0x3300000, 0x3000000, 0x3480000,
577
 
    0x3580000, 0x6280000, 0x6400000, 0x6080000, 0x6680000,
578
 
    0x6500000, 0x6180000, 0x6200000, 0x6100000, 0x6700000,
579
 
    0x6780000, 0x6600000, 0x6380000, 0x6300000, 0x6000000,
580
 
    0x6480000, 0x6580000, 0x5A80000, 0x5C00000, 0x5880000,
581
 
    0x5E80000, 0x5D00000, 0x5980000, 0x5A00000, 0x5900000,
582
 
    0x5F00000, 0x5F80000, 0x5E00000, 0x5B80000, 0x5B00000,
583
 
    0x5800000, 0x5C80000, 0x5D80000, 0x1280000, 0x1400000,
584
 
    0x1080000, 0x1680000, 0x1500000, 0x1180000, 0x1200000,
585
 
    0x1100000, 0x1700000, 0x1780000, 0x1600000, 0x1380000,
586
 
    0x1300000, 0x1000000, 0x1480000, 0x1580000, 0x2A80000,
587
 
    0x2C00000, 0x2880000, 0x2E80000, 0x2D00000, 0x2980000,
588
 
    0x2A00000, 0x2900000, 0x2F00000, 0x2F80000, 0x2E00000,
589
 
    0x2B80000, 0x2B00000, 0x2800000, 0x2C80000, 0x2D80000,
590
 
    0x1A80000, 0x1C00000, 0x1880000, 0x1E80000, 0x1D00000,
591
 
    0x1980000, 0x1A00000, 0x1900000, 0x1F00000, 0x1F80000,
592
 
    0x1E00000, 0x1B80000, 0x1B00000, 0x1800000, 0x1C80000,
593
 
    0x1D80000
594
 
  }, {
595
 
    0x30000002, 0x60000002, 0x38000002, 0x8000002,
596
 
    0x28000002, 0x78000002, 0x68000002, 0x40000002, 
597
 
    0x20000002, 0x50000002, 0x48000002, 0x70000002, 
598
 
    0x2,        0x18000002, 0x58000002, 0x10000002, 
599
 
    0xB0000005, 0xE0000005, 0xB8000005, 0x88000005,
600
 
    0xA8000005, 0xF8000005, 0xE8000005, 0xC0000005,
601
 
    0xA0000005, 0xD0000005, 0xC8000005, 0xF0000005, 
602
 
    0x80000005, 0x98000005, 0xD8000005, 0x90000005, 
603
 
    0x30000005, 0x60000005, 0x38000005, 0x8000005, 
604
 
    0x28000005, 0x78000005, 0x68000005, 0x40000005,
605
 
    0x20000005, 0x50000005, 0x48000005, 0x70000005, 
606
 
    0x5,        0x18000005, 0x58000005, 0x10000005, 
607
 
    0x30000000, 0x60000000, 0x38000000, 0x8000000, 
608
 
    0x28000000, 0x78000000, 0x68000000, 0x40000000, 
609
 
    0x20000000, 0x50000000, 0x48000000, 0x70000000,
610
 
    0x0,        0x18000000, 0x58000000, 0x10000000, 
611
 
    0xB0000003, 0xE0000003, 0xB8000003, 0x88000003, 
612
 
    0xA8000003, 0xF8000003, 0xE8000003, 0xC0000003, 
613
 
    0xA0000003, 0xD0000003, 0xC8000003, 0xF0000003, 
614
 
    0x80000003, 0x98000003, 0xD8000003, 0x90000003,
615
 
    0x30000001, 0x60000001, 0x38000001, 0x8000001,
616
 
    0x28000001, 0x78000001, 0x68000001, 0x40000001, 
617
 
    0x20000001, 0x50000001, 0x48000001, 0x70000001, 
618
 
    0x1,        0x18000001, 0x58000001, 0x10000001, 
619
 
    0xB0000000, 0xE0000000, 0xB8000000, 0x88000000,
620
 
    0xA8000000, 0xF8000000, 0xE8000000, 0xC0000000,
621
 
    0xA0000000, 0xD0000000, 0xC8000000, 0xF0000000, 
622
 
    0x80000000, 0x98000000, 0xD8000000, 0x90000000, 
623
 
    0xB0000006, 0xE0000006, 0xB8000006, 0x88000006, 
624
 
    0xA8000006, 0xF8000006, 0xE8000006, 0xC0000006,
625
 
    0xA0000006, 0xD0000006, 0xC8000006, 0xF0000006,
626
 
    0x80000006, 0x98000006, 0xD8000006, 0x90000006, 
627
 
    0xB0000001, 0xE0000001, 0xB8000001, 0x88000001, 
628
 
    0xA8000001, 0xF8000001, 0xE8000001, 0xC0000001, 
629
 
    0xA0000001, 0xD0000001, 0xC8000001, 0xF0000001,
630
 
    0x80000001, 0x98000001, 0xD8000001, 0x90000001,
631
 
    0x30000003, 0x60000003, 0x38000003, 0x8000003, 
632
 
    0x28000003, 0x78000003, 0x68000003, 0x40000003, 
633
 
    0x20000003, 0x50000003, 0x48000003, 0x70000003, 
634
 
    0x3,        0x18000003, 0x58000003, 0x10000003,
635
 
    0x30000004, 0x60000004, 0x38000004, 0x8000004,
636
 
    0x28000004, 0x78000004, 0x68000004, 0x40000004, 
637
 
    0x20000004, 0x50000004, 0x48000004, 0x70000004, 
638
 
    0x4,        0x18000004, 0x58000004, 0x10000004, 
639
 
    0xB0000002, 0xE0000002, 0xB8000002, 0x88000002,
640
 
    0xA8000002, 0xF8000002, 0xE8000002, 0xC0000002,
641
 
    0xA0000002, 0xD0000002, 0xC8000002, 0xF0000002, 
642
 
    0x80000002, 0x98000002, 0xD8000002, 0x90000002, 
643
 
    0xB0000004, 0xE0000004, 0xB8000004, 0x88000004, 
644
 
    0xA8000004, 0xF8000004, 0xE8000004, 0xC0000004,
645
 
    0xA0000004, 0xD0000004, 0xC8000004, 0xF0000004,
646
 
    0x80000004, 0x98000004, 0xD8000004, 0x90000004, 
647
 
    0x30000006, 0x60000006, 0x38000006, 0x8000006, 
648
 
    0x28000006, 0x78000006, 0x68000006, 0x40000006, 
649
 
    0x20000006, 0x50000006, 0x48000006, 0x70000006,
650
 
    0x6,        0x18000006, 0x58000006, 0x10000006, 
651
 
    0xB0000007, 0xE0000007, 0xB8000007, 0x88000007, 
652
 
    0xA8000007, 0xF8000007, 0xE8000007, 0xC0000007, 
653
 
    0xA0000007, 0xD0000007, 0xC8000007, 0xF0000007, 
654
 
    0x80000007, 0x98000007, 0xD8000007, 0x90000007,
655
 
    0x30000007, 0x60000007, 0x38000007, 0x8000007,
656
 
    0x28000007, 0x78000007, 0x68000007, 0x40000007, 
657
 
    0x20000007, 0x50000007, 0x48000007, 0x70000007, 
658
 
    0x7,        0x18000007, 0x58000007, 0x10000007
659
 
  }, {
660
 
    0xE8,  0xD8,  0xA0,  0x88,  0x98,  0xF8,  0xA8,  0xC8,  0x80,  0xD0,
661
 
    0xF0,  0xB8,  0xB0,  0xC0,  0x90,  0xE0,  0x7E8, 0x7D8, 0x7A0, 0x788,
662
 
    0x798, 0x7F8, 0x7A8, 0x7C8, 0x780, 0x7D0, 0x7F0, 0x7B8, 0x7B0, 0x7C0,
663
 
    0x790, 0x7E0, 0x6E8, 0x6D8, 0x6A0, 0x688, 0x698, 0x6F8, 0x6A8, 0x6C8,
664
 
    0x680, 0x6D0, 0x6F0, 0x6B8, 0x6B0, 0x6C0, 0x690, 0x6E0, 0x68,  0x58,
665
 
    0x20,  0x8,   0x18,  0x78,  0x28,   0x48,  0x0,   0x50,  0x70,  0x38,
666
 
    0x30,  0x40,  0x10,  0x60,  0x2E8, 0x2D8, 0x2A0, 0x288, 0x298, 0x2F8,
667
 
    0x2A8, 0x2C8, 0x280, 0x2D0, 0x2F0, 0x2B8, 0x2B0, 0x2C0, 0x290, 0x2E0,
668
 
    0x3E8, 0x3D8, 0x3A0, 0x388, 0x398, 0x3F8, 0x3A8, 0x3C8, 0x380, 0x3D0,
669
 
    0x3F0, 0x3B8, 0x3B0, 0x3C0, 0x390, 0x3E0, 0x568, 0x558, 0x520, 0x508,
670
 
    0x518, 0x578, 0x528, 0x548, 0x500, 0x550, 0x570, 0x538, 0x530, 0x540,
671
 
    0x510, 0x560, 0x268, 0x258, 0x220, 0x208, 0x218, 0x278, 0x228, 0x248,
672
 
    0x200, 0x250, 0x270, 0x238, 0x230, 0x240, 0x210, 0x260, 0x4E8, 0x4D8,
673
 
    0x4A0, 0x488, 0x498, 0x4F8, 0x4A8, 0x4C8, 0x480, 0x4D0, 0x4F0, 0x4B8,
674
 
    0x4B0, 0x4C0, 0x490, 0x4E0, 0x168, 0x158, 0x120, 0x108, 0x118, 0x178,
675
 
    0x128, 0x148, 0x100, 0x150, 0x170, 0x138, 0x130, 0x140, 0x110, 0x160,
676
 
    0x1E8, 0x1D8, 0x1A0, 0x188, 0x198, 0x1F8, 0x1A8, 0x1C8, 0x180, 0x1D0,
677
 
    0x1F0, 0x1B8, 0x1B0, 0x1C0, 0x190, 0x1E0, 0x768, 0x758, 0x720, 0x708,
678
 
    0x718, 0x778, 0x728, 0x748, 0x700, 0x750, 0x770, 0x738, 0x730, 0x740,
679
 
    0x710, 0x760, 0x368, 0x358, 0x320, 0x308, 0x318, 0x378, 0x328, 0x348,
680
 
    0x300, 0x350, 0x370, 0x338, 0x330, 0x340, 0x310, 0x360, 0x5E8, 0x5D8,
681
 
    0x5A0, 0x588, 0x598, 0x5F8, 0x5A8, 0x5C8, 0x580, 0x5D0, 0x5F0, 0x5B8,
682
 
    0x5B0, 0x5C0, 0x590, 0x5E0, 0x468, 0x458, 0x420, 0x408, 0x418, 0x478,
683
 
    0x428, 0x448, 0x400, 0x450, 0x470, 0x438, 0x430, 0x440, 0x410, 0x460,
684
 
    0x668, 0x658, 0x620, 0x608, 0x618, 0x678, 0x628, 0x648, 0x600, 0x650,
685
 
    0x670, 0x638, 0x630, 0x640, 0x610, 0x660
686
 
  }
 
486
unsigned rhash_gost_sbox[4][256] = {
 
487
        {
 
488
                0x72000, 0x75000, 0x74800, 0x71000, 0x76800,
 
489
                0x74000, 0x70000, 0x77000, 0x73000, 0x75800,
 
490
                0x70800, 0x76000, 0x73800, 0x77800, 0x72800,
 
491
                0x71800, 0x5A000, 0x5D000, 0x5C800, 0x59000,
 
492
                0x5E800, 0x5C000, 0x58000, 0x5F000, 0x5B000,
 
493
                0x5D800, 0x58800, 0x5E000, 0x5B800, 0x5F800,
 
494
                0x5A800, 0x59800, 0x22000, 0x25000, 0x24800,
 
495
                0x21000, 0x26800, 0x24000, 0x20000, 0x27000,
 
496
                0x23000, 0x25800, 0x20800, 0x26000, 0x23800,
 
497
                0x27800, 0x22800, 0x21800, 0x62000, 0x65000,
 
498
                0x64800, 0x61000, 0x66800, 0x64000, 0x60000,
 
499
                0x67000, 0x63000, 0x65800, 0x60800, 0x66000,
 
500
                0x63800, 0x67800, 0x62800, 0x61800, 0x32000,
 
501
                0x35000, 0x34800, 0x31000, 0x36800, 0x34000,
 
502
                0x30000, 0x37000, 0x33000, 0x35800, 0x30800,
 
503
                0x36000, 0x33800, 0x37800, 0x32800, 0x31800,
 
504
                0x6A000, 0x6D000, 0x6C800, 0x69000, 0x6E800,
 
505
                0x6C000, 0x68000, 0x6F000, 0x6B000, 0x6D800,
 
506
                0x68800, 0x6E000, 0x6B800, 0x6F800, 0x6A800,
 
507
                0x69800, 0x7A000, 0x7D000, 0x7C800, 0x79000,
 
508
                0x7E800, 0x7C000, 0x78000, 0x7F000, 0x7B000,
 
509
                0x7D800, 0x78800, 0x7E000, 0x7B800, 0x7F800,
 
510
                0x7A800, 0x79800, 0x52000, 0x55000, 0x54800,
 
511
                0x51000, 0x56800, 0x54000, 0x50000, 0x57000,
 
512
                0x53000, 0x55800, 0x50800, 0x56000, 0x53800,
 
513
                0x57800, 0x52800, 0x51800, 0x12000, 0x15000,
 
514
                0x14800, 0x11000, 0x16800, 0x14000, 0x10000,
 
515
                0x17000, 0x13000, 0x15800, 0x10800, 0x16000,
 
516
                0x13800, 0x17800, 0x12800, 0x11800, 0x1A000,
 
517
                0x1D000, 0x1C800, 0x19000, 0x1E800, 0x1C000,
 
518
                0x18000, 0x1F000, 0x1B000, 0x1D800, 0x18800,
 
519
                0x1E000, 0x1B800, 0x1F800, 0x1A800, 0x19800,
 
520
                0x42000, 0x45000, 0x44800, 0x41000, 0x46800,
 
521
                0x44000, 0x40000, 0x47000, 0x43000, 0x45800,
 
522
                0x40800, 0x46000, 0x43800, 0x47800, 0x42800,
 
523
                0x41800, 0xA000,  0xD000,  0xC800,  0x9000,
 
524
                0xE800,  0xC000,  0x8000,  0xF000,  0xB000,
 
525
                0xD800,  0x8800,  0xE000,  0xB800,  0xF800,
 
526
                0xA800,  0x9800,  0x2000,  0x5000,  0x4800,
 
527
                0x1000,  0x6800,  0x4000,  0x0,     0x7000,
 
528
                0x3000,  0x5800,  0x800,   0x6000,  0x3800,
 
529
                0x7800,  0x2800,  0x1800,  0x3A000, 0x3D000,
 
530
                0x3C800, 0x39000, 0x3E800, 0x3C000, 0x38000,
 
531
                0x3F000, 0x3B000, 0x3D800, 0x38800, 0x3E000,
 
532
                0x3B800, 0x3F800, 0x3A800, 0x39800, 0x2A000,
 
533
                0x2D000, 0x2C800, 0x29000, 0x2E800, 0x2C000,
 
534
                0x28000, 0x2F000, 0x2B000, 0x2D800, 0x28800,
 
535
                0x2E000, 0x2B800, 0x2F800, 0x2A800, 0x29800,
 
536
                0x4A000, 0x4D000, 0x4C800, 0x49000, 0x4E800,
 
537
                0x4C000, 0x48000, 0x4F000, 0x4B000, 0x4D800,
 
538
                0x48800, 0x4E000, 0x4B800, 0x4F800, 0x4A800,
 
539
                0x49800
 
540
        }, {
 
541
                0x3A80000, 0x3C00000, 0x3880000, 0x3E80000, 0x3D00000,
 
542
                0x3980000, 0x3A00000, 0x3900000, 0x3F00000, 0x3F80000,
 
543
                0x3E00000, 0x3B80000, 0x3B00000, 0x3800000, 0x3C80000,
 
544
                0x3D80000, 0x6A80000, 0x6C00000, 0x6880000, 0x6E80000,
 
545
                0x6D00000, 0x6980000, 0x6A00000, 0x6900000, 0x6F00000,
 
546
                0x6F80000, 0x6E00000, 0x6B80000, 0x6B00000, 0x6800000,
 
547
                0x6C80000, 0x6D80000, 0x5280000, 0x5400000, 0x5080000,
 
548
                0x5680000, 0x5500000, 0x5180000, 0x5200000, 0x5100000,
 
549
                0x5700000, 0x5780000, 0x5600000, 0x5380000, 0x5300000,
 
550
                0x5000000, 0x5480000, 0x5580000, 0xA80000,  0xC00000,
 
551
                0x880000,  0xE80000,  0xD00000,  0x980000,  0xA00000,
 
552
                0x900000,  0xF00000,  0xF80000,  0xE00000,  0xB80000,
 
553
                0xB00000,  0x800000,  0xC80000,  0xD80000,  0x280000,
 
554
                0x400000,  0x80000,   0x680000,  0x500000,  0x180000,
 
555
                0x200000,  0x100000,  0x700000,  0x780000,  0x600000,
 
556
                0x380000,  0x300000,  0x0,       0x480000,  0x580000,
 
557
                0x4280000, 0x4400000, 0x4080000, 0x4680000, 0x4500000,
 
558
                0x4180000, 0x4200000, 0x4100000, 0x4700000, 0x4780000,
 
559
                0x4600000, 0x4380000, 0x4300000, 0x4000000, 0x4480000,
 
560
                0x4580000, 0x4A80000, 0x4C00000, 0x4880000, 0x4E80000,
 
561
                0x4D00000, 0x4980000, 0x4A00000, 0x4900000, 0x4F00000,
 
562
                0x4F80000, 0x4E00000, 0x4B80000, 0x4B00000, 0x4800000,
 
563
                0x4C80000, 0x4D80000, 0x7A80000, 0x7C00000, 0x7880000,
 
564
                0x7E80000, 0x7D00000, 0x7980000, 0x7A00000, 0x7900000,
 
565
                0x7F00000, 0x7F80000, 0x7E00000, 0x7B80000, 0x7B00000,
 
566
                0x7800000, 0x7C80000, 0x7D80000, 0x7280000, 0x7400000,
 
567
                0x7080000, 0x7680000, 0x7500000, 0x7180000, 0x7200000,
 
568
                0x7100000, 0x7700000, 0x7780000, 0x7600000, 0x7380000,
 
569
                0x7300000, 0x7000000, 0x7480000, 0x7580000, 0x2280000,
 
570
                0x2400000, 0x2080000, 0x2680000, 0x2500000, 0x2180000,
 
571
                0x2200000, 0x2100000, 0x2700000, 0x2780000, 0x2600000,
 
572
                0x2380000, 0x2300000, 0x2000000, 0x2480000, 0x2580000,
 
573
                0x3280000, 0x3400000, 0x3080000, 0x3680000, 0x3500000,
 
574
                0x3180000, 0x3200000, 0x3100000, 0x3700000, 0x3780000,
 
575
                0x3600000, 0x3380000, 0x3300000, 0x3000000, 0x3480000,
 
576
                0x3580000, 0x6280000, 0x6400000, 0x6080000, 0x6680000,
 
577
                0x6500000, 0x6180000, 0x6200000, 0x6100000, 0x6700000,
 
578
                0x6780000, 0x6600000, 0x6380000, 0x6300000, 0x6000000,
 
579
                0x6480000, 0x6580000, 0x5A80000, 0x5C00000, 0x5880000,
 
580
                0x5E80000, 0x5D00000, 0x5980000, 0x5A00000, 0x5900000,
 
581
                0x5F00000, 0x5F80000, 0x5E00000, 0x5B80000, 0x5B00000,
 
582
                0x5800000, 0x5C80000, 0x5D80000, 0x1280000, 0x1400000,
 
583
                0x1080000, 0x1680000, 0x1500000, 0x1180000, 0x1200000,
 
584
                0x1100000, 0x1700000, 0x1780000, 0x1600000, 0x1380000,
 
585
                0x1300000, 0x1000000, 0x1480000, 0x1580000, 0x2A80000,
 
586
                0x2C00000, 0x2880000, 0x2E80000, 0x2D00000, 0x2980000,
 
587
                0x2A00000, 0x2900000, 0x2F00000, 0x2F80000, 0x2E00000,
 
588
                0x2B80000, 0x2B00000, 0x2800000, 0x2C80000, 0x2D80000,
 
589
                0x1A80000, 0x1C00000, 0x1880000, 0x1E80000, 0x1D00000,
 
590
                0x1980000, 0x1A00000, 0x1900000, 0x1F00000, 0x1F80000,
 
591
                0x1E00000, 0x1B80000, 0x1B00000, 0x1800000, 0x1C80000,
 
592
                0x1D80000
 
593
        }, {
 
594
                0x30000002, 0x60000002, 0x38000002, 0x8000002,
 
595
                0x28000002, 0x78000002, 0x68000002, 0x40000002, 
 
596
                0x20000002, 0x50000002, 0x48000002, 0x70000002, 
 
597
                0x2,        0x18000002, 0x58000002, 0x10000002, 
 
598
                0xB0000005, 0xE0000005, 0xB8000005, 0x88000005,
 
599
                0xA8000005, 0xF8000005, 0xE8000005, 0xC0000005,
 
600
                0xA0000005, 0xD0000005, 0xC8000005, 0xF0000005, 
 
601
                0x80000005, 0x98000005, 0xD8000005, 0x90000005, 
 
602
                0x30000005, 0x60000005, 0x38000005, 0x8000005, 
 
603
                0x28000005, 0x78000005, 0x68000005, 0x40000005,
 
604
                0x20000005, 0x50000005, 0x48000005, 0x70000005, 
 
605
                0x5,        0x18000005, 0x58000005, 0x10000005, 
 
606
                0x30000000, 0x60000000, 0x38000000, 0x8000000, 
 
607
                0x28000000, 0x78000000, 0x68000000, 0x40000000, 
 
608
                0x20000000, 0x50000000, 0x48000000, 0x70000000,
 
609
                0x0,        0x18000000, 0x58000000, 0x10000000, 
 
610
                0xB0000003, 0xE0000003, 0xB8000003, 0x88000003, 
 
611
                0xA8000003, 0xF8000003, 0xE8000003, 0xC0000003, 
 
612
                0xA0000003, 0xD0000003, 0xC8000003, 0xF0000003, 
 
613
                0x80000003, 0x98000003, 0xD8000003, 0x90000003,
 
614
                0x30000001, 0x60000001, 0x38000001, 0x8000001,
 
615
                0x28000001, 0x78000001, 0x68000001, 0x40000001, 
 
616
                0x20000001, 0x50000001, 0x48000001, 0x70000001, 
 
617
                0x1,        0x18000001, 0x58000001, 0x10000001, 
 
618
                0xB0000000, 0xE0000000, 0xB8000000, 0x88000000,
 
619
                0xA8000000, 0xF8000000, 0xE8000000, 0xC0000000,
 
620
                0xA0000000, 0xD0000000, 0xC8000000, 0xF0000000, 
 
621
                0x80000000, 0x98000000, 0xD8000000, 0x90000000, 
 
622
                0xB0000006, 0xE0000006, 0xB8000006, 0x88000006, 
 
623
                0xA8000006, 0xF8000006, 0xE8000006, 0xC0000006,
 
624
                0xA0000006, 0xD0000006, 0xC8000006, 0xF0000006,
 
625
                0x80000006, 0x98000006, 0xD8000006, 0x90000006, 
 
626
                0xB0000001, 0xE0000001, 0xB8000001, 0x88000001, 
 
627
                0xA8000001, 0xF8000001, 0xE8000001, 0xC0000001, 
 
628
                0xA0000001, 0xD0000001, 0xC8000001, 0xF0000001,
 
629
                0x80000001, 0x98000001, 0xD8000001, 0x90000001,
 
630
                0x30000003, 0x60000003, 0x38000003, 0x8000003, 
 
631
                0x28000003, 0x78000003, 0x68000003, 0x40000003, 
 
632
                0x20000003, 0x50000003, 0x48000003, 0x70000003, 
 
633
                0x3,        0x18000003, 0x58000003, 0x10000003,
 
634
                0x30000004, 0x60000004, 0x38000004, 0x8000004,
 
635
                0x28000004, 0x78000004, 0x68000004, 0x40000004, 
 
636
                0x20000004, 0x50000004, 0x48000004, 0x70000004, 
 
637
                0x4,        0x18000004, 0x58000004, 0x10000004, 
 
638
                0xB0000002, 0xE0000002, 0xB8000002, 0x88000002,
 
639
                0xA8000002, 0xF8000002, 0xE8000002, 0xC0000002,
 
640
                0xA0000002, 0xD0000002, 0xC8000002, 0xF0000002, 
 
641
                0x80000002, 0x98000002, 0xD8000002, 0x90000002, 
 
642
                0xB0000004, 0xE0000004, 0xB8000004, 0x88000004, 
 
643
                0xA8000004, 0xF8000004, 0xE8000004, 0xC0000004,
 
644
                0xA0000004, 0xD0000004, 0xC8000004, 0xF0000004,
 
645
                0x80000004, 0x98000004, 0xD8000004, 0x90000004, 
 
646
                0x30000006, 0x60000006, 0x38000006, 0x8000006, 
 
647
                0x28000006, 0x78000006, 0x68000006, 0x40000006, 
 
648
                0x20000006, 0x50000006, 0x48000006, 0x70000006,
 
649
                0x6,        0x18000006, 0x58000006, 0x10000006, 
 
650
                0xB0000007, 0xE0000007, 0xB8000007, 0x88000007, 
 
651
                0xA8000007, 0xF8000007, 0xE8000007, 0xC0000007, 
 
652
                0xA0000007, 0xD0000007, 0xC8000007, 0xF0000007, 
 
653
                0x80000007, 0x98000007, 0xD8000007, 0x90000007,
 
654
                0x30000007, 0x60000007, 0x38000007, 0x8000007,
 
655
                0x28000007, 0x78000007, 0x68000007, 0x40000007, 
 
656
                0x20000007, 0x50000007, 0x48000007, 0x70000007, 
 
657
                0x7,        0x18000007, 0x58000007, 0x10000007
 
658
        }, {
 
659
                0xE8,  0xD8,  0xA0,  0x88,  0x98,  0xF8,  0xA8,  0xC8,  0x80,  0xD0,
 
660
                0xF0,  0xB8,  0xB0,  0xC0,  0x90,  0xE0,  0x7E8, 0x7D8, 0x7A0, 0x788,
 
661
                0x798, 0x7F8, 0x7A8, 0x7C8, 0x780, 0x7D0, 0x7F0, 0x7B8, 0x7B0, 0x7C0,
 
662
                0x790, 0x7E0, 0x6E8, 0x6D8, 0x6A0, 0x688, 0x698, 0x6F8, 0x6A8, 0x6C8,
 
663
                0x680, 0x6D0, 0x6F0, 0x6B8, 0x6B0, 0x6C0, 0x690, 0x6E0, 0x68,  0x58,
 
664
                0x20,  0x8,   0x18,  0x78,  0x28,  0x48,  0x0,   0x50,  0x70,  0x38,
 
665
                0x30,  0x40,  0x10,  0x60,  0x2E8, 0x2D8, 0x2A0, 0x288, 0x298, 0x2F8,
 
666
                0x2A8, 0x2C8, 0x280, 0x2D0, 0x2F0, 0x2B8, 0x2B0, 0x2C0, 0x290, 0x2E0,
 
667
                0x3E8, 0x3D8, 0x3A0, 0x388, 0x398, 0x3F8, 0x3A8, 0x3C8, 0x380, 0x3D0,
 
668
                0x3F0, 0x3B8, 0x3B0, 0x3C0, 0x390, 0x3E0, 0x568, 0x558, 0x520, 0x508,
 
669
                0x518, 0x578, 0x528, 0x548, 0x500, 0x550, 0x570, 0x538, 0x530, 0x540,
 
670
                0x510, 0x560, 0x268, 0x258, 0x220, 0x208, 0x218, 0x278, 0x228, 0x248,
 
671
                0x200, 0x250, 0x270, 0x238, 0x230, 0x240, 0x210, 0x260, 0x4E8, 0x4D8,
 
672
                0x4A0, 0x488, 0x498, 0x4F8, 0x4A8, 0x4C8, 0x480, 0x4D0, 0x4F0, 0x4B8,
 
673
                0x4B0, 0x4C0, 0x490, 0x4E0, 0x168, 0x158, 0x120, 0x108, 0x118, 0x178,
 
674
                0x128, 0x148, 0x100, 0x150, 0x170, 0x138, 0x130, 0x140, 0x110, 0x160,
 
675
                0x1E8, 0x1D8, 0x1A0, 0x188, 0x198, 0x1F8, 0x1A8, 0x1C8, 0x180, 0x1D0,
 
676
                0x1F0, 0x1B8, 0x1B0, 0x1C0, 0x190, 0x1E0, 0x768, 0x758, 0x720, 0x708,
 
677
                0x718, 0x778, 0x728, 0x748, 0x700, 0x750, 0x770, 0x738, 0x730, 0x740,
 
678
                0x710, 0x760, 0x368, 0x358, 0x320, 0x308, 0x318, 0x378, 0x328, 0x348,
 
679
                0x300, 0x350, 0x370, 0x338, 0x330, 0x340, 0x310, 0x360, 0x5E8, 0x5D8,
 
680
                0x5A0, 0x588, 0x598, 0x5F8, 0x5A8, 0x5C8, 0x580, 0x5D0, 0x5F0, 0x5B8,
 
681
                0x5B0, 0x5C0, 0x590, 0x5E0, 0x468, 0x458, 0x420, 0x408, 0x418, 0x478,
 
682
                0x428, 0x448, 0x400, 0x450, 0x470, 0x438, 0x430, 0x440, 0x410, 0x460,
 
683
                0x668, 0x658, 0x620, 0x608, 0x618, 0x678, 0x628, 0x648, 0x600, 0x650,
 
684
                0x670, 0x638, 0x630, 0x640, 0x610, 0x660
 
685
        }
687
686
};
688
687
 
689
688
/* pre-initialized GOST lookup tables based on rotated S-Box */
690
 
unsigned gost_sbox_cryptpro[4][256] = {
691
 
  {
692
 
    0x2d000, 0x2a000, 0x2a800, 0x2b000, 0x2c000,
693
 
    0x28800, 0x29800, 0x2b800, 0x2e800, 0x2e000,
694
 
    0x2f000, 0x28000, 0x2c800, 0x29000, 0x2d800,
695
 
    0x2f800, 0x7d000, 0x7a000, 0x7a800, 0x7b000,
696
 
    0x7c000, 0x78800, 0x79800, 0x7b800, 0x7e800,
697
 
    0x7e000, 0x7f000, 0x78000, 0x7c800, 0x79000,
698
 
    0x7d800, 0x7f800, 0x25000, 0x22000, 0x22800,
699
 
    0x23000, 0x24000, 0x20800, 0x21800, 0x23800,
700
 
    0x26800, 0x26000, 0x27000, 0x20000, 0x24800,
701
 
    0x21000, 0x25800, 0x27800, 0x5000,  0x2000,
702
 
    0x2800,  0x3000,  0x4000,  0x800,   0x1800,
703
 
    0x3800,  0x6800,  0x6000,  0x7000,  0x0,
704
 
    0x4800,  0x1000,  0x5800,  0x7800,  0x15000,
705
 
    0x12000, 0x12800, 0x13000, 0x14000, 0x10800,
706
 
    0x11800, 0x13800, 0x16800, 0x16000, 0x17000,
707
 
    0x10000, 0x14800, 0x11000, 0x15800, 0x17800,
708
 
    0x6d000, 0x6a000, 0x6a800, 0x6b000, 0x6c000,
709
 
    0x68800, 0x69800, 0x6b800, 0x6e800, 0x6e000,
710
 
    0x6f000, 0x68000, 0x6c800, 0x69000, 0x6d800,
711
 
    0x6f800, 0x5d000, 0x5a000, 0x5a800, 0x5b000,
712
 
    0x5c000, 0x58800, 0x59800, 0x5b800, 0x5e800,
713
 
    0x5e000, 0x5f000, 0x58000, 0x5c800, 0x59000,
714
 
    0x5d800, 0x5f800, 0x4d000, 0x4a000, 0x4a800,
715
 
    0x4b000, 0x4c000, 0x48800, 0x49800, 0x4b800,
716
 
    0x4e800, 0x4e000, 0x4f000, 0x48000, 0x4c800,
717
 
    0x49000, 0x4d800, 0x4f800, 0xd000,  0xa000,
718
 
    0xa800,  0xb000,  0xc000,  0x8800,  0x9800,
719
 
    0xb800,  0xe800,  0xe000,  0xf000,  0x8000,
720
 
    0xc800,  0x9000,  0xd800,  0xf800,  0x3d000,
721
 
    0x3a000, 0x3a800, 0x3b000, 0x3c000, 0x38800,
722
 
    0x39800, 0x3b800, 0x3e800, 0x3e000, 0x3f000,
723
 
    0x38000, 0x3c800, 0x39000, 0x3d800, 0x3f800,
724
 
    0x35000, 0x32000, 0x32800, 0x33000, 0x34000,
725
 
    0x30800, 0x31800, 0x33800, 0x36800, 0x36000,
726
 
    0x37000, 0x30000, 0x34800, 0x31000, 0x35800,
727
 
    0x37800, 0x1d000, 0x1a000, 0x1a800, 0x1b000,
728
 
    0x1c000, 0x18800, 0x19800, 0x1b800, 0x1e800,
729
 
    0x1e000, 0x1f000, 0x18000, 0x1c800, 0x19000,
730
 
    0x1d800, 0x1f800, 0x65000, 0x62000, 0x62800,
731
 
    0x63000, 0x64000, 0x60800, 0x61800, 0x63800,
732
 
    0x66800, 0x66000, 0x67000, 0x60000, 0x64800,
733
 
    0x61000, 0x65800, 0x67800, 0x75000, 0x72000,
734
 
    0x72800, 0x73000, 0x74000, 0x70800, 0x71800,
735
 
    0x73800, 0x76800, 0x76000, 0x77000, 0x70000,
736
 
    0x74800, 0x71000, 0x75800, 0x77800, 0x55000,
737
 
    0x52000, 0x52800, 0x53000, 0x54000, 0x50800,
738
 
    0x51800, 0x53800, 0x56800, 0x56000, 0x57000,
739
 
    0x50000, 0x54800, 0x51000, 0x55800, 0x57800,
740
 
    0x45000, 0x42000, 0x42800, 0x43000, 0x44000,
741
 
    0x40800, 0x41800, 0x43800, 0x46800, 0x46000,
742
 
    0x47000, 0x40000, 0x44800, 0x41000, 0x45800, 0x47800
743
 
  }, {
744
 
    0x2380000, 0x2780000, 0x2600000, 0x2700000, 0x2480000,
745
 
    0x2200000, 0x2080000, 0x2000000, 0x2180000, 0x2580000,
746
 
    0x2280000, 0x2100000, 0x2300000, 0x2500000, 0x2400000,
747
 
    0x2680000, 0x5380000, 0x5780000, 0x5600000, 0x5700000,
748
 
    0x5480000, 0x5200000, 0x5080000, 0x5000000, 0x5180000,
749
 
    0x5580000, 0x5280000, 0x5100000, 0x5300000, 0x5500000,
750
 
    0x5400000, 0x5680000, 0x3b80000, 0x3f80000, 0x3e00000,
751
 
    0x3f00000, 0x3c80000, 0x3a00000, 0x3880000, 0x3800000,
752
 
    0x3980000, 0x3d80000, 0x3a80000, 0x3900000, 0x3b00000,
753
 
    0x3d00000, 0x3c00000, 0x3e80000, 0x6380000, 0x6780000,
754
 
    0x6600000, 0x6700000, 0x6480000, 0x6200000, 0x6080000,
755
 
    0x6000000, 0x6180000, 0x6580000, 0x6280000, 0x6100000,
756
 
    0x6300000, 0x6500000, 0x6400000, 0x6680000, 0x380000,
757
 
    0x780000,  0x600000,  0x700000,  0x480000,  0x200000,
758
 
    0x80000,   0x0,       0x180000,  0x580000,  0x280000,
759
 
    0x100000,  0x300000,  0x500000,  0x400000,  0x680000,
760
 
    0x7b80000, 0x7f80000, 0x7e00000, 0x7f00000, 0x7c80000,
761
 
    0x7a00000, 0x7880000, 0x7800000, 0x7980000, 0x7d80000,
762
 
    0x7a80000, 0x7900000, 0x7b00000, 0x7d00000, 0x7c00000,
763
 
    0x7e80000, 0x1380000, 0x1780000, 0x1600000, 0x1700000,
764
 
    0x1480000, 0x1200000, 0x1080000, 0x1000000, 0x1180000,
765
 
    0x1580000, 0x1280000, 0x1100000, 0x1300000, 0x1500000,
766
 
    0x1400000, 0x1680000, 0x4380000, 0x4780000, 0x4600000,
767
 
    0x4700000, 0x4480000, 0x4200000, 0x4080000, 0x4000000,
768
 
    0x4180000, 0x4580000, 0x4280000, 0x4100000, 0x4300000,
769
 
    0x4500000, 0x4400000, 0x4680000, 0x7380000, 0x7780000,
770
 
    0x7600000, 0x7700000, 0x7480000, 0x7200000, 0x7080000,
771
 
    0x7000000, 0x7180000, 0x7580000, 0x7280000, 0x7100000,
772
 
    0x7300000, 0x7500000, 0x7400000, 0x7680000, 0xb80000,
773
 
    0xf80000,  0xe00000,  0xf00000,  0xc80000,  0xa00000,
774
 
    0x880000,  0x800000,  0x980000,  0xd80000,  0xa80000,
775
 
    0x900000,  0xb00000,  0xd00000,  0xc00000,  0xe80000,
776
 
    0x3380000, 0x3780000, 0x3600000, 0x3700000, 0x3480000,
777
 
    0x3200000, 0x3080000, 0x3000000, 0x3180000, 0x3580000,
778
 
    0x3280000, 0x3100000, 0x3300000, 0x3500000, 0x3400000,
779
 
    0x3680000, 0x2b80000, 0x2f80000, 0x2e00000, 0x2f00000,
780
 
    0x2c80000, 0x2a00000, 0x2880000, 0x2800000, 0x2980000,
781
 
    0x2d80000, 0x2a80000, 0x2900000, 0x2b00000, 0x2d00000,
782
 
    0x2c00000, 0x2e80000, 0x6b80000, 0x6f80000, 0x6e00000,
783
 
    0x6f00000, 0x6c80000, 0x6a00000, 0x6880000, 0x6800000,
784
 
    0x6980000, 0x6d80000, 0x6a80000, 0x6900000, 0x6b00000,
785
 
    0x6d00000, 0x6c00000, 0x6e80000, 0x5b80000, 0x5f80000,
786
 
    0x5e00000, 0x5f00000, 0x5c80000, 0x5a00000, 0x5880000,
787
 
    0x5800000, 0x5980000, 0x5d80000, 0x5a80000, 0x5900000,
788
 
    0x5b00000, 0x5d00000, 0x5c00000, 0x5e80000, 0x4b80000,
789
 
    0x4f80000, 0x4e00000, 0x4f00000, 0x4c80000, 0x4a00000,
790
 
    0x4880000, 0x4800000, 0x4980000, 0x4d80000, 0x4a80000,
791
 
    0x4900000, 0x4b00000, 0x4d00000, 0x4c00000, 0x4e80000,
792
 
    0x1b80000, 0x1f80000, 0x1e00000, 0x1f00000, 0x1c80000,
793
 
    0x1a00000, 0x1880000, 0x1800000, 0x1980000, 0x1d80000,
794
 
    0x1a80000, 0x1900000, 0x1b00000, 0x1d00000, 0x1c00000,
795
 
    0x1e80000
796
 
  }, {
797
 
    0xb8000003, 0xb0000003, 0xa0000003, 0xd8000003, 0xc8000003,
798
 
    0xe0000003, 0x90000003, 0xd0000003, 0x88000003, 0xc0000003,
799
 
    0x80000003, 0xf0000003, 0xf8000003, 0xe8000003, 0x98000003,
800
 
    0xa8000003, 0x38000003, 0x30000003, 0x20000003, 0x58000003,
801
 
    0x48000003, 0x60000003, 0x10000003, 0x50000003, 0x8000003,
802
 
    0x40000003, 0x3,        0x70000003, 0x78000003, 0x68000003,
803
 
    0x18000003, 0x28000003, 0x38000001, 0x30000001, 0x20000001,
804
 
    0x58000001, 0x48000001, 0x60000001, 0x10000001, 0x50000001,
805
 
    0x8000001,  0x40000001, 0x1,        0x70000001, 0x78000001,
806
 
    0x68000001, 0x18000001, 0x28000001, 0x38000002, 0x30000002,
807
 
    0x20000002, 0x58000002, 0x48000002, 0x60000002, 0x10000002,
808
 
    0x50000002, 0x8000002,  0x40000002, 0x2,        0x70000002,
809
 
    0x78000002, 0x68000002, 0x18000002, 0x28000002, 0xb8000006,
810
 
    0xb0000006, 0xa0000006, 0xd8000006, 0xc8000006, 0xe0000006,
811
 
    0x90000006, 0xd0000006, 0x88000006, 0xc0000006, 0x80000006,
812
 
    0xf0000006, 0xf8000006, 0xe8000006, 0x98000006, 0xa8000006,
813
 
    0xb8000004, 0xb0000004, 0xa0000004, 0xd8000004, 0xc8000004,
814
 
    0xe0000004, 0x90000004, 0xd0000004, 0x88000004, 0xc0000004,
815
 
    0x80000004, 0xf0000004, 0xf8000004, 0xe8000004, 0x98000004,
816
 
    0xa8000004, 0xb8000007, 0xb0000007, 0xa0000007, 0xd8000007,
817
 
    0xc8000007, 0xe0000007, 0x90000007, 0xd0000007, 0x88000007,
818
 
    0xc0000007, 0x80000007, 0xf0000007, 0xf8000007, 0xe8000007,
819
 
    0x98000007, 0xa8000007, 0x38000000, 0x30000000, 0x20000000,
820
 
    0x58000000, 0x48000000, 0x60000000, 0x10000000, 0x50000000,
821
 
    0x8000000,  0x40000000, 0x0,        0x70000000, 0x78000000,
822
 
    0x68000000, 0x18000000, 0x28000000, 0x38000005, 0x30000005,
823
 
    0x20000005, 0x58000005, 0x48000005, 0x60000005, 0x10000005,
824
 
    0x50000005, 0x8000005,  0x40000005, 0x5,        0x70000005,
825
 
    0x78000005, 0x68000005, 0x18000005, 0x28000005, 0xb8000000,
826
 
    0xb0000000, 0xa0000000, 0xd8000000, 0xc8000000, 0xe0000000,
827
 
    0x90000000, 0xd0000000, 0x88000000, 0xc0000000, 0x80000000,
828
 
    0xf0000000, 0xf8000000, 0xe8000000, 0x98000000, 0xa8000000,
829
 
    0xb8000002, 0xb0000002, 0xa0000002, 0xd8000002, 0xc8000002,
830
 
    0xe0000002, 0x90000002, 0xd0000002, 0x88000002, 0xc0000002,
831
 
    0x80000002, 0xf0000002, 0xf8000002, 0xe8000002, 0x98000002,
832
 
    0xa8000002, 0xb8000005, 0xb0000005, 0xa0000005, 0xd8000005,
833
 
    0xc8000005, 0xe0000005, 0x90000005, 0xd0000005, 0x88000005,
834
 
    0xc0000005, 0x80000005, 0xf0000005, 0xf8000005, 0xe8000005,
835
 
    0x98000005, 0xa8000005, 0x38000004, 0x30000004, 0x20000004,
836
 
    0x58000004, 0x48000004, 0x60000004, 0x10000004, 0x50000004,
837
 
    0x8000004,  0x40000004, 0x4,        0x70000004, 0x78000004,
838
 
    0x68000004, 0x18000004, 0x28000004, 0x38000007, 0x30000007,
839
 
    0x20000007, 0x58000007, 0x48000007, 0x60000007, 0x10000007,
840
 
    0x50000007, 0x8000007,  0x40000007, 0x7,        0x70000007,
841
 
    0x78000007, 0x68000007, 0x18000007, 0x28000007, 0x38000006,
842
 
    0x30000006, 0x20000006, 0x58000006, 0x48000006, 0x60000006,
843
 
    0x10000006, 0x50000006, 0x8000006,  0x40000006, 0x6,
844
 
    0x70000006, 0x78000006, 0x68000006, 0x18000006, 0x28000006,
845
 
    0xb8000001, 0xb0000001, 0xa0000001, 0xd8000001, 0xc8000001,
846
 
    0xe0000001, 0x90000001, 0xd0000001, 0x88000001, 0xc0000001,
847
 
    0x80000001, 0xf0000001, 0xf8000001, 0xe8000001, 0x98000001,
848
 
    0xa8000001
849
 
  }, {
850
 
    0xe8,  0xf0,  0xa0,  0x88,  0xb8,  0x80,  0xa8,  0xd0,  0x98,  0xe0,
851
 
    0xc0,  0xf8,  0xb0,  0x90,  0xc8,  0xd8,  0x1e8, 0x1f0, 0x1a0, 0x188,
852
 
    0x1b8, 0x180, 0x1a8, 0x1d0, 0x198, 0x1e0, 0x1c0, 0x1f8, 0x1b0, 0x190,
853
 
    0x1c8, 0x1d8, 0x568, 0x570, 0x520, 0x508, 0x538, 0x500, 0x528, 0x550,
854
 
    0x518, 0x560, 0x540, 0x578, 0x530, 0x510, 0x548, 0x558, 0x4e8, 0x4f0,
855
 
    0x4a0, 0x488, 0x4b8, 0x480, 0x4a8, 0x4d0, 0x498, 0x4e0, 0x4c0, 0x4f8,
856
 
    0x4b0, 0x490, 0x4c8, 0x4d8, 0x2e8, 0x2f0, 0x2a0, 0x288, 0x2b8, 0x280,
857
 
    0x2a8, 0x2d0, 0x298, 0x2e0, 0x2c0, 0x2f8, 0x2b0, 0x290, 0x2c8, 0x2d8,
858
 
    0x5e8, 0x5f0, 0x5a0, 0x588, 0x5b8, 0x580, 0x5a8, 0x5d0, 0x598, 0x5e0,
859
 
    0x5c0, 0x5f8, 0x5b0, 0x590, 0x5c8, 0x5d8, 0x268, 0x270, 0x220, 0x208,
860
 
    0x238, 0x200, 0x228, 0x250, 0x218, 0x260, 0x240, 0x278, 0x230, 0x210,
861
 
    0x248, 0x258, 0x7e8, 0x7f0, 0x7a0, 0x788, 0x7b8, 0x780, 0x7a8, 0x7d0,
862
 
    0x798, 0x7e0, 0x7c0, 0x7f8, 0x7b0, 0x790, 0x7c8, 0x7d8, 0x468, 0x470,
863
 
    0x420, 0x408, 0x438, 0x400, 0x428, 0x450, 0x418, 0x460, 0x440, 0x478,
864
 
    0x430, 0x410, 0x448, 0x458, 0x368, 0x370, 0x320, 0x308, 0x338, 0x300,
865
 
    0x328, 0x350, 0x318, 0x360, 0x340, 0x378, 0x330, 0x310, 0x348, 0x358,
866
 
    0x3e8, 0x3f0, 0x3a0, 0x388, 0x3b8, 0x380, 0x3a8, 0x3d0, 0x398, 0x3e0,
867
 
    0x3c0, 0x3f8, 0x3b0, 0x390, 0x3c8, 0x3d8, 0x768, 0x770, 0x720, 0x708,
868
 
    0x738, 0x700, 0x728, 0x750, 0x718, 0x760, 0x740, 0x778, 0x730, 0x710,
869
 
    0x748, 0x758, 0x6e8, 0x6f0, 0x6a0, 0x688, 0x6b8, 0x680, 0x6a8, 0x6d0,
870
 
    0x698, 0x6e0, 0x6c0, 0x6f8, 0x6b0, 0x690, 0x6c8, 0x6d8, 0x68,  0x70,
871
 
    0x20,  0x8,   0x38,  0x0,   0x28,  0x50,  0x18,  0x60,  0x40,  0x78,
872
 
    0x30,  0x10,  0x48,  0x58,  0x168, 0x170, 0x120, 0x108, 0x138, 0x100,
873
 
    0x128, 0x150, 0x118, 0x160, 0x140, 0x178, 0x130, 0x110, 0x148, 0x158,
874
 
    0x668, 0x670, 0x620, 0x608, 0x638, 0x600, 0x628, 0x650, 0x618, 0x660,
875
 
    0x640, 0x678, 0x630, 0x610, 0x648, 0x658
876
 
  }
 
689
unsigned rhash_gost_sbox_cryptpro[4][256] = {
 
690
        {
 
691
                0x2d000, 0x2a000, 0x2a800, 0x2b000, 0x2c000,
 
692
                0x28800, 0x29800, 0x2b800, 0x2e800, 0x2e000,
 
693
                0x2f000, 0x28000, 0x2c800, 0x29000, 0x2d800,
 
694
                0x2f800, 0x7d000, 0x7a000, 0x7a800, 0x7b000,
 
695
                0x7c000, 0x78800, 0x79800, 0x7b800, 0x7e800,
 
696
                0x7e000, 0x7f000, 0x78000, 0x7c800, 0x79000,
 
697
                0x7d800, 0x7f800, 0x25000, 0x22000, 0x22800,
 
698
                0x23000, 0x24000, 0x20800, 0x21800, 0x23800,
 
699
                0x26800, 0x26000, 0x27000, 0x20000, 0x24800,
 
700
                0x21000, 0x25800, 0x27800, 0x5000,  0x2000,
 
701
                0x2800,  0x3000,  0x4000,  0x800,   0x1800,
 
702
                0x3800,  0x6800,  0x6000,  0x7000,  0x0,
 
703
                0x4800,  0x1000,  0x5800,  0x7800,  0x15000,
 
704
                0x12000, 0x12800, 0x13000, 0x14000, 0x10800,
 
705
                0x11800, 0x13800, 0x16800, 0x16000, 0x17000,
 
706
                0x10000, 0x14800, 0x11000, 0x15800, 0x17800,
 
707
                0x6d000, 0x6a000, 0x6a800, 0x6b000, 0x6c000,
 
708
                0x68800, 0x69800, 0x6b800, 0x6e800, 0x6e000,
 
709
                0x6f000, 0x68000, 0x6c800, 0x69000, 0x6d800,
 
710
                0x6f800, 0x5d000, 0x5a000, 0x5a800, 0x5b000,
 
711
                0x5c000, 0x58800, 0x59800, 0x5b800, 0x5e800,
 
712
                0x5e000, 0x5f000, 0x58000, 0x5c800, 0x59000,
 
713
                0x5d800, 0x5f800, 0x4d000, 0x4a000, 0x4a800,
 
714
                0x4b000, 0x4c000, 0x48800, 0x49800, 0x4b800,
 
715
                0x4e800, 0x4e000, 0x4f000, 0x48000, 0x4c800,
 
716
                0x49000, 0x4d800, 0x4f800, 0xd000,  0xa000,
 
717
                0xa800,  0xb000,  0xc000,  0x8800,  0x9800,
 
718
                0xb800,  0xe800,  0xe000,  0xf000,  0x8000,
 
719
                0xc800,  0x9000,  0xd800,  0xf800,  0x3d000,
 
720
                0x3a000, 0x3a800, 0x3b000, 0x3c000, 0x38800,
 
721
                0x39800, 0x3b800, 0x3e800, 0x3e000, 0x3f000,
 
722
                0x38000, 0x3c800, 0x39000, 0x3d800, 0x3f800,
 
723
                0x35000, 0x32000, 0x32800, 0x33000, 0x34000,
 
724
                0x30800, 0x31800, 0x33800, 0x36800, 0x36000,
 
725
                0x37000, 0x30000, 0x34800, 0x31000, 0x35800,
 
726
                0x37800, 0x1d000, 0x1a000, 0x1a800, 0x1b000,
 
727
                0x1c000, 0x18800, 0x19800, 0x1b800, 0x1e800,
 
728
                0x1e000, 0x1f000, 0x18000, 0x1c800, 0x19000,
 
729
                0x1d800, 0x1f800, 0x65000, 0x62000, 0x62800,
 
730
                0x63000, 0x64000, 0x60800, 0x61800, 0x63800,
 
731
                0x66800, 0x66000, 0x67000, 0x60000, 0x64800,
 
732
                0x61000, 0x65800, 0x67800, 0x75000, 0x72000,
 
733
                0x72800, 0x73000, 0x74000, 0x70800, 0x71800,
 
734
                0x73800, 0x76800, 0x76000, 0x77000, 0x70000,
 
735
                0x74800, 0x71000, 0x75800, 0x77800, 0x55000,
 
736
                0x52000, 0x52800, 0x53000, 0x54000, 0x50800,
 
737
                0x51800, 0x53800, 0x56800, 0x56000, 0x57000,
 
738
                0x50000, 0x54800, 0x51000, 0x55800, 0x57800,
 
739
                0x45000, 0x42000, 0x42800, 0x43000, 0x44000,
 
740
                0x40800, 0x41800, 0x43800, 0x46800, 0x46000,
 
741
                0x47000, 0x40000, 0x44800, 0x41000, 0x45800, 0x47800
 
742
        }, {
 
743
                0x2380000, 0x2780000, 0x2600000, 0x2700000, 0x2480000,
 
744
                0x2200000, 0x2080000, 0x2000000, 0x2180000, 0x2580000,
 
745
                0x2280000, 0x2100000, 0x2300000, 0x2500000, 0x2400000,
 
746
                0x2680000, 0x5380000, 0x5780000, 0x5600000, 0x5700000,
 
747
                0x5480000, 0x5200000, 0x5080000, 0x5000000, 0x5180000,
 
748
                0x5580000, 0x5280000, 0x5100000, 0x5300000, 0x5500000,
 
749
                0x5400000, 0x5680000, 0x3b80000, 0x3f80000, 0x3e00000,
 
750
                0x3f00000, 0x3c80000, 0x3a00000, 0x3880000, 0x3800000,
 
751
                0x3980000, 0x3d80000, 0x3a80000, 0x3900000, 0x3b00000,
 
752
                0x3d00000, 0x3c00000, 0x3e80000, 0x6380000, 0x6780000,
 
753
                0x6600000, 0x6700000, 0x6480000, 0x6200000, 0x6080000,
 
754
                0x6000000, 0x6180000, 0x6580000, 0x6280000, 0x6100000,
 
755
                0x6300000, 0x6500000, 0x6400000, 0x6680000, 0x380000,
 
756
                0x780000,  0x600000,  0x700000,  0x480000,  0x200000,
 
757
                0x80000,   0x0,       0x180000,  0x580000,  0x280000,
 
758
                0x100000,  0x300000,  0x500000,  0x400000,  0x680000,
 
759
                0x7b80000, 0x7f80000, 0x7e00000, 0x7f00000, 0x7c80000,
 
760
                0x7a00000, 0x7880000, 0x7800000, 0x7980000, 0x7d80000,
 
761
                0x7a80000, 0x7900000, 0x7b00000, 0x7d00000, 0x7c00000,
 
762
                0x7e80000, 0x1380000, 0x1780000, 0x1600000, 0x1700000,
 
763
                0x1480000, 0x1200000, 0x1080000, 0x1000000, 0x1180000,
 
764
                0x1580000, 0x1280000, 0x1100000, 0x1300000, 0x1500000,
 
765
                0x1400000, 0x1680000, 0x4380000, 0x4780000, 0x4600000,
 
766
                0x4700000, 0x4480000, 0x4200000, 0x4080000, 0x4000000,
 
767
                0x4180000, 0x4580000, 0x4280000, 0x4100000, 0x4300000,
 
768
                0x4500000, 0x4400000, 0x4680000, 0x7380000, 0x7780000,
 
769
                0x7600000, 0x7700000, 0x7480000, 0x7200000, 0x7080000,
 
770
                0x7000000, 0x7180000, 0x7580000, 0x7280000, 0x7100000,
 
771
                0x7300000, 0x7500000, 0x7400000, 0x7680000, 0xb80000,
 
772
                0xf80000,  0xe00000,  0xf00000,  0xc80000,  0xa00000,
 
773
                0x880000,  0x800000,  0x980000,  0xd80000,  0xa80000,
 
774
                0x900000,  0xb00000,  0xd00000,  0xc00000,  0xe80000,
 
775
                0x3380000, 0x3780000, 0x3600000, 0x3700000, 0x3480000,
 
776
                0x3200000, 0x3080000, 0x3000000, 0x3180000, 0x3580000,
 
777
                0x3280000, 0x3100000, 0x3300000, 0x3500000, 0x3400000,
 
778
                0x3680000, 0x2b80000, 0x2f80000, 0x2e00000, 0x2f00000,
 
779
                0x2c80000, 0x2a00000, 0x2880000, 0x2800000, 0x2980000,
 
780
                0x2d80000, 0x2a80000, 0x2900000, 0x2b00000, 0x2d00000,
 
781
                0x2c00000, 0x2e80000, 0x6b80000, 0x6f80000, 0x6e00000,
 
782
                0x6f00000, 0x6c80000, 0x6a00000, 0x6880000, 0x6800000,
 
783
                0x6980000, 0x6d80000, 0x6a80000, 0x6900000, 0x6b00000,
 
784
                0x6d00000, 0x6c00000, 0x6e80000, 0x5b80000, 0x5f80000,
 
785
                0x5e00000, 0x5f00000, 0x5c80000, 0x5a00000, 0x5880000,
 
786
                0x5800000, 0x5980000, 0x5d80000, 0x5a80000, 0x5900000,
 
787
                0x5b00000, 0x5d00000, 0x5c00000, 0x5e80000, 0x4b80000,
 
788
                0x4f80000, 0x4e00000, 0x4f00000, 0x4c80000, 0x4a00000,
 
789
                0x4880000, 0x4800000, 0x4980000, 0x4d80000, 0x4a80000,
 
790
                0x4900000, 0x4b00000, 0x4d00000, 0x4c00000, 0x4e80000,
 
791
                0x1b80000, 0x1f80000, 0x1e00000, 0x1f00000, 0x1c80000,
 
792
                0x1a00000, 0x1880000, 0x1800000, 0x1980000, 0x1d80000,
 
793
                0x1a80000, 0x1900000, 0x1b00000, 0x1d00000, 0x1c00000,
 
794
                0x1e80000
 
795
        }, {
 
796
                0xb8000003, 0xb0000003, 0xa0000003, 0xd8000003, 0xc8000003,
 
797
                0xe0000003, 0x90000003, 0xd0000003, 0x88000003, 0xc0000003,
 
798
                0x80000003, 0xf0000003, 0xf8000003, 0xe8000003, 0x98000003,
 
799
                0xa8000003, 0x38000003, 0x30000003, 0x20000003, 0x58000003,
 
800
                0x48000003, 0x60000003, 0x10000003, 0x50000003, 0x8000003,
 
801
                0x40000003, 0x3,        0x70000003, 0x78000003, 0x68000003,
 
802
                0x18000003, 0x28000003, 0x38000001, 0x30000001, 0x20000001,
 
803
                0x58000001, 0x48000001, 0x60000001, 0x10000001, 0x50000001,
 
804
                0x8000001,  0x40000001, 0x1,        0x70000001, 0x78000001,
 
805
                0x68000001, 0x18000001, 0x28000001, 0x38000002, 0x30000002,
 
806
                0x20000002, 0x58000002, 0x48000002, 0x60000002, 0x10000002,
 
807
                0x50000002, 0x8000002,  0x40000002, 0x2,        0x70000002,
 
808
                0x78000002, 0x68000002, 0x18000002, 0x28000002, 0xb8000006,
 
809
                0xb0000006, 0xa0000006, 0xd8000006, 0xc8000006, 0xe0000006,
 
810
                0x90000006, 0xd0000006, 0x88000006, 0xc0000006, 0x80000006,
 
811
                0xf0000006, 0xf8000006, 0xe8000006, 0x98000006, 0xa8000006,
 
812
                0xb8000004, 0xb0000004, 0xa0000004, 0xd8000004, 0xc8000004,
 
813
                0xe0000004, 0x90000004, 0xd0000004, 0x88000004, 0xc0000004,
 
814
                0x80000004, 0xf0000004, 0xf8000004, 0xe8000004, 0x98000004,
 
815
                0xa8000004, 0xb8000007, 0xb0000007, 0xa0000007, 0xd8000007,
 
816
                0xc8000007, 0xe0000007, 0x90000007, 0xd0000007, 0x88000007,
 
817
                0xc0000007, 0x80000007, 0xf0000007, 0xf8000007, 0xe8000007,
 
818
                0x98000007, 0xa8000007, 0x38000000, 0x30000000, 0x20000000,
 
819
                0x58000000, 0x48000000, 0x60000000, 0x10000000, 0x50000000,
 
820
                0x8000000,  0x40000000, 0x0,        0x70000000, 0x78000000,
 
821
                0x68000000, 0x18000000, 0x28000000, 0x38000005, 0x30000005,
 
822
                0x20000005, 0x58000005, 0x48000005, 0x60000005, 0x10000005,
 
823
                0x50000005, 0x8000005,  0x40000005, 0x5,        0x70000005,
 
824
                0x78000005, 0x68000005, 0x18000005, 0x28000005, 0xb8000000,
 
825
                0xb0000000, 0xa0000000, 0xd8000000, 0xc8000000, 0xe0000000,
 
826
                0x90000000, 0xd0000000, 0x88000000, 0xc0000000, 0x80000000,
 
827
                0xf0000000, 0xf8000000, 0xe8000000, 0x98000000, 0xa8000000,
 
828
                0xb8000002, 0xb0000002, 0xa0000002, 0xd8000002, 0xc8000002,
 
829
                0xe0000002, 0x90000002, 0xd0000002, 0x88000002, 0xc0000002,
 
830
                0x80000002, 0xf0000002, 0xf8000002, 0xe8000002, 0x98000002,
 
831
                0xa8000002, 0xb8000005, 0xb0000005, 0xa0000005, 0xd8000005,
 
832
                0xc8000005, 0xe0000005, 0x90000005, 0xd0000005, 0x88000005,
 
833
                0xc0000005, 0x80000005, 0xf0000005, 0xf8000005, 0xe8000005,
 
834
                0x98000005, 0xa8000005, 0x38000004, 0x30000004, 0x20000004,
 
835
                0x58000004, 0x48000004, 0x60000004, 0x10000004, 0x50000004,
 
836
                0x8000004,  0x40000004, 0x4,        0x70000004, 0x78000004,
 
837
                0x68000004, 0x18000004, 0x28000004, 0x38000007, 0x30000007,
 
838
                0x20000007, 0x58000007, 0x48000007, 0x60000007, 0x10000007,
 
839
                0x50000007, 0x8000007,  0x40000007, 0x7,        0x70000007,
 
840
                0x78000007, 0x68000007, 0x18000007, 0x28000007, 0x38000006,
 
841
                0x30000006, 0x20000006, 0x58000006, 0x48000006, 0x60000006,
 
842
                0x10000006, 0x50000006, 0x8000006,  0x40000006, 0x6,
 
843
                0x70000006, 0x78000006, 0x68000006, 0x18000006, 0x28000006,
 
844
                0xb8000001, 0xb0000001, 0xa0000001, 0xd8000001, 0xc8000001,
 
845
                0xe0000001, 0x90000001, 0xd0000001, 0x88000001, 0xc0000001,
 
846
                0x80000001, 0xf0000001, 0xf8000001, 0xe8000001, 0x98000001,
 
847
                0xa8000001
 
848
        }, {
 
849
                0xe8,  0xf0,  0xa0,  0x88,  0xb8,  0x80,  0xa8,  0xd0,  0x98,  0xe0,
 
850
                0xc0,  0xf8,  0xb0,  0x90,  0xc8,  0xd8,  0x1e8, 0x1f0, 0x1a0, 0x188,
 
851
                0x1b8, 0x180, 0x1a8, 0x1d0, 0x198, 0x1e0, 0x1c0, 0x1f8, 0x1b0, 0x190,
 
852
                0x1c8, 0x1d8, 0x568, 0x570, 0x520, 0x508, 0x538, 0x500, 0x528, 0x550,
 
853
                0x518, 0x560, 0x540, 0x578, 0x530, 0x510, 0x548, 0x558, 0x4e8, 0x4f0,
 
854
                0x4a0, 0x488, 0x4b8, 0x480, 0x4a8, 0x4d0, 0x498, 0x4e0, 0x4c0, 0x4f8,
 
855
                0x4b0, 0x490, 0x4c8, 0x4d8, 0x2e8, 0x2f0, 0x2a0, 0x288, 0x2b8, 0x280,
 
856
                0x2a8, 0x2d0, 0x298, 0x2e0, 0x2c0, 0x2f8, 0x2b0, 0x290, 0x2c8, 0x2d8,
 
857
                0x5e8, 0x5f0, 0x5a0, 0x588, 0x5b8, 0x580, 0x5a8, 0x5d0, 0x598, 0x5e0,
 
858
                0x5c0, 0x5f8, 0x5b0, 0x590, 0x5c8, 0x5d8, 0x268, 0x270, 0x220, 0x208,
 
859
                0x238, 0x200, 0x228, 0x250, 0x218, 0x260, 0x240, 0x278, 0x230, 0x210,
 
860
                0x248, 0x258, 0x7e8, 0x7f0, 0x7a0, 0x788, 0x7b8, 0x780, 0x7a8, 0x7d0,
 
861
                0x798, 0x7e0, 0x7c0, 0x7f8, 0x7b0, 0x790, 0x7c8, 0x7d8, 0x468, 0x470,
 
862
                0x420, 0x408, 0x438, 0x400, 0x428, 0x450, 0x418, 0x460, 0x440, 0x478,
 
863
                0x430, 0x410, 0x448, 0x458, 0x368, 0x370, 0x320, 0x308, 0x338, 0x300,
 
864
                0x328, 0x350, 0x318, 0x360, 0x340, 0x378, 0x330, 0x310, 0x348, 0x358,
 
865
                0x3e8, 0x3f0, 0x3a0, 0x388, 0x3b8, 0x380, 0x3a8, 0x3d0, 0x398, 0x3e0,
 
866
                0x3c0, 0x3f8, 0x3b0, 0x390, 0x3c8, 0x3d8, 0x768, 0x770, 0x720, 0x708,
 
867
                0x738, 0x700, 0x728, 0x750, 0x718, 0x760, 0x740, 0x778, 0x730, 0x710,
 
868
                0x748, 0x758, 0x6e8, 0x6f0, 0x6a0, 0x688, 0x6b8, 0x680, 0x6a8, 0x6d0,
 
869
                0x698, 0x6e0, 0x6c0, 0x6f8, 0x6b0, 0x690, 0x6c8, 0x6d8, 0x68,  0x70,
 
870
                0x20,  0x8,   0x38,  0x0,   0x28,  0x50,  0x18,  0x60,  0x40,  0x78,
 
871
                0x30,  0x10,  0x48,  0x58,  0x168, 0x170, 0x120, 0x108, 0x138, 0x100,
 
872
                0x128, 0x150, 0x118, 0x160, 0x140, 0x178, 0x130, 0x110, 0x148, 0x158,
 
873
                0x668, 0x670, 0x620, 0x608, 0x638, 0x600, 0x628, 0x650, 0x618, 0x660,
 
874
                0x640, 0x678, 0x630, 0x610, 0x648, 0x658
 
875
        }
877
876
};
878
877
 
879
878