powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пример использования ГОСТ 21847-89
4 сообщений из 4, страница 1 из 1
Пример использования ГОСТ 21847-89
    #34645263
RUSYA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нашёл в инете 2 реализации:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
/*
 * The GOST 28147-89 cipher
 *
 * This is based on the 25 Movember 1993 draft translation
 * by Aleksandr Malchik, with Whitfield Diffie, of the Government
 * Standard of the U.S.S.R. GOST 28149-89, "Cryptographic Transformation
 * Algorithm", effective 1 July 1990.  (Whitfield.Diffie@eng.sun.com)
 *
 * That is a draft, and may contain errors, which will be faithfully
 * reflected here, along with possible exciting new bugs.
 *
 * Some details have been cleared up by the paper "Soviet Encryption
 * Algorithm" by Josef Pieprzyk and Leonid Tombak of the University
 * of Wollongong, New South Wales.  (josef/leo@cs.adfa.oz.au)
 *
 * The standard is written by A. Zabotin (project leader), G.P. Glazkov,
 * and V.B. Isaeva.  It was accepted and introduced into use by the
 * action of the State Standards Committee of the USSR on 2 June 89 as
 * No. 1409.  It was to be reviewed in 1993, but whether anyone wishes
 * to take on this obligation from the USSR is questionable.
 *
 * This code is placed in the public domain.
 */

/*
 * If you read the standard, it belabors the point of copying corresponding
 * bits from point A to point B quite a bit.  It helps to understand that
 * the standard is uniformly little-endian, although it numbers bits from
 * 1 rather than 0, so bit n has value 2^(n-1).  The least significant bit
 * of the 32-bit words that are manipulated in the algorithm is the first,
 * lowest-numbered, in the bit string.
 */


/* A 32-bit data type */
#ifdef __alpha  /* Any other 64-bit machines? */
typedef unsigned int word32;
#else
typedef unsigned long word32;
#endif

/*
 * The standard does not specify the contents of the 8 4 bit->4 bit
 * substitution boxes, saying they're a parameter of the network
 * being set up.  For illustration purposes here, I have used
 * the first rows of the 8 S-boxes from the DES.  (Note that the
 * DES S-boxes are numbered starting from 1 at the msb.  In keeping
 * with the rest of the GOST, I have used little-endian numbering.
 * Thus, k8 is S-box 1.
 *
 * Obviously, a careful look at the cryptographic properties of the cipher
 * must be undertaken before "production" substitution boxes are defined.
 *
 * The standard also does not specify a standard bit-string representation
 * for the contents of these blocks.
 */
static unsigned char const k8[16] = {
	14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7 }; 
static unsigned char const k7[16] = {
	15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10 };
static unsigned char const k6[16] = {
	10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8 };
static unsigned char const k5[16] = {
	 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15 };
static unsigned char const k4[16] = {
	 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9 };
static unsigned char const k3[16] = {
	12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11 };
static unsigned char const k2[16] = {
	 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1 };
static unsigned char const k1[16] = {
	13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7 };

/* Byte-at-a-time substitution boxes */
static unsigned char k87[256];
static unsigned char k65[256];
static unsigned char k43[256];
static unsigned char k21[256];

/*
 * Build byte-at-a-time subtitution tables.
 * This must be called once for global setup.
 */
void
kboxinit(void)
{
	int i;
	for (i = 0; i < 256; i++) {
		k87[i] = k8[i >> 4] << 4 | k7[i & 15];
		k65[i] = k6[i >> 4] << 4 | k5[i & 15];
		k43[i] = k4[i >> 4] << 4 | k3[i & 15];
		k21[i] = k2[i >> 4] << 4 | k1[i & 15];
	}
}

/*
 * Do the substitution and rotation that are the core of the operation,
 * like the expansion, substitution and permutation of the DES.
 * It would be possible to perform DES-like optimisations and store
 * the table entries as 32-bit words, already rotated, but the
 * efficiency gain is questionable.
 *
 * This should be inlined for maximum speed
 */
#if __GNUC__
__inline__
#endif
static word32
f(word32 x)
{
	/* Do substitutions */
#if 0
	/* This is annoyingly slow */
	x = k8[x>>28 & 15] << 28 | k7[x>>24 & 15] << 24 |
	    k6[x>>20 & 15] << 20 | k5[x>>16 & 15] << 16 |
	    k4[x>>12 & 15] << 12 | k3[x>> 8 & 15] <<  8 |
	    k2[x>> 4 & 15] <<  4 | k1[x     & 15];
#else
	/* This is faster */
	x = k87[x>>24 & 255] << 24 | k65[x>>16 & 255] << 16 |
	    k43[x>> 8 & 255] <<  8 | k21[x & 255];
#endif

	/* Rotate left 11 bits */
	return x<<11 | x>>(32-11);
}

/*
 * The GOST standard defines the input in terms of bits 1..64, with
 * bit 1 being the lsb of in[0] and bit 64 being the msb of in[1].
 *
 * The keys are defined similarly, with bit 256 being the msb of key[7].
 */
void
gostcrypt(word32 const in[2], word32 out[2], word32 const key[8])
{
	register word32 n1, n2; /* As named in the GOST */

	n1 = in[0];
	n2 = in[1];

	/* Instead of swapping halves, swap names each round */
	n2 ^= f(n1+key[0]);
	n1 ^= f(n2+key[1]);
	n2 ^= f(n1+key[2]);
	n1 ^= f(n2+key[3]);
	n2 ^= f(n1+key[4]);
	n1 ^= f(n2+key[5]);
	n2 ^= f(n1+key[6]);
	n1 ^= f(n2+key[7]);

	n2 ^= f(n1+key[0]);
	n1 ^= f(n2+key[1]);
	n2 ^= f(n1+key[2]);
	n1 ^= f(n2+key[3]);
	n2 ^= f(n1+key[4]);
	n1 ^= f(n2+key[5]);
	n2 ^= f(n1+key[6]);
	n1 ^= f(n2+key[7]);

	n2 ^= f(n1+key[0]);
	n1 ^= f(n2+key[1]);
	n2 ^= f(n1+key[2]);
	n1 ^= f(n2+key[3]);
	n2 ^= f(n1+key[4]);
	n1 ^= f(n2+key[5]);
	n2 ^= f(n1+key[6]);
	n1 ^= f(n2+key[7]);

	n2 ^= f(n1+key[7]);
	n1 ^= f(n2+key[6]);
	n2 ^= f(n1+key[5]);
	n1 ^= f(n2+key[4]);
	n2 ^= f(n1+key[3]);
	n1 ^= f(n2+key[2]);
	n2 ^= f(n1+key[1]);
	n1 ^= f(n2+key[0]);

	/* There is no swap after the last round */
	out[0] = n2;
	out[1] = n1;
}
	

/*
 * The key schedule is somewhat different for decryption.
 * (The key table is used once forward and three times backward.)
 * You could define an expanded key, or just write the code twice,
 * as done here.
 */
void
gostdecrypt(word32 const in[2], word32 out[2], word32 const key[8])
{
	register word32 n1, n2; /* As named in the GOST */

	n1 = in[0];
	n2 = in[1];

	n2 ^= f(n1+key[0]);
	n1 ^= f(n2+key[1]);
	n2 ^= f(n1+key[2]);
	n1 ^= f(n2+key[3]);
	n2 ^= f(n1+key[4]);
	n1 ^= f(n2+key[5]);
	n2 ^= f(n1+key[6]);
	n1 ^= f(n2+key[7]);

	n2 ^= f(n1+key[7]);
	n1 ^= f(n2+key[6]);
	n2 ^= f(n1+key[5]);
	n1 ^= f(n2+key[4]);
	n2 ^= f(n1+key[3]);
	n1 ^= f(n2+key[2]);
	n2 ^= f(n1+key[1]);
	n1 ^= f(n2+key[0]);

	n2 ^= f(n1+key[7]);
	n1 ^= f(n2+key[6]);
	n2 ^= f(n1+key[5]);
	n1 ^= f(n2+key[4]);
	n2 ^= f(n1+key[3]);
	n1 ^= f(n2+key[2]);
	n2 ^= f(n1+key[1]);
	n1 ^= f(n2+key[0]);

	n2 ^= f(n1+key[7]);
	n1 ^= f(n2+key[6]);
	n2 ^= f(n1+key[5]);
	n1 ^= f(n2+key[4]);
	n2 ^= f(n1+key[3]);
	n1 ^= f(n2+key[2]);
	n2 ^= f(n1+key[1]);
	n1 ^= f(n2+key[0]);

	out[0] = n2;
	out[1] = n1;
}

/*
 * The GOST "Output feedback" standard.  It seems closer morally
 * to the counter feedback mode some people have proposed for DES.
 * The avoidance of the short cycles that are possible in OFB seems
 * like a Good Thing.
 *
 * Calling it the stream mode makes more sense.
 *
 * The IV is encrypted with the key to produce the initial counter value.
 * Then, for each output block, a constant is added, modulo 2^32-1
 * (0 is represented as all-ones, not all-zeros), to each half of
 * the counter, and the counter is encrypted to produce the value
 * to XOR with the output.
 *
 * Len is the number of blocks.  Sub-block encryption is
 * left as an exercise for the user.  Remember that the
 * standard defines everything in a little-endian manner,
 * so you want to use the low bit of gamma[0] first.
 *
 * OFB is, of course, self-inverse, so there is only one function.
 */

/* The constants for addition */
#define C1 0x01010104
#define C2 0x01010101

void
gostofb(word32 const *in, word32 *out, int len,
	word32 const iv[2], word32 const key[8])
{
	word32 temp[2];         /* Counter */
	word32 gamma[2];        /* Output XOR value */

	/* Compute starting value for counter */
	gostcrypt(iv, temp, key);

	while (len--) {
		temp[0] += C2;
		if (temp[0] < C2)       /* Wrap modulo 2^32? */
			temp[0]++;      /* Make it modulo 2^32-1 */
		temp[1] += C1;
		if (temp[1] < C1)       /* Wrap modulo 2^32? */
			temp[1]++;      /* Make it modulo 2^32-1 */

		gostcrypt(temp, gamma, key);

		*out++ = *in++ ^ gamma[0];
		*out++ = *in++ ^ gamma[1];
	}
}

/*
 * The CFB mode is just what you'd expect.  Each block of ciphertext y[] is
 * derived from the input x[] by the following pseudocode:
 * y[i] = x[i] ^ gostcrypt(y[i-1])
 * x[i] = y[i] ^ gostcrypt(y[i-1])
 * Where y[-1] is the IV.
 *
 * The IV is modified in place.  Again, len is in *blocks*.
 */

void
gostcfbencrypt(word32 const *in, word32 *out, int len,
	       word32 iv[ 2 ], word32 const key[ 8 ])
{
	while (len--) {
		gostcrypt(iv, iv, key);
		iv[ 0 ] = *out++ ^= iv[ 0 ];
		iv[ 1 ] = *out++ ^= iv[ 1 ];
	}
}

void
gostcfbdecrypt(word32 const *in, word32 *out, int len,
	       word32 iv[ 2 ], word32 const key[ 8 ])
{
	word32 t;
	while (len--) {
		gostcrypt(iv, iv, key);
		t = *out;
		*out++ ^= iv[ 0 ];
		iv[ 0 ] = t;
		t = *out;
		*out++ ^= iv[ 1 ];
		iv[ 1 ] = t;
	}
}


/*
 * The message suthetication code uses only 16 of the 32 rounds.
 * There *is* a swap after the 16th round.
 * The last block should be padded to 64 bits with zeros.
 * len is the number of *blocks* in the input.
 */
void
gostmac(word32 const *in, int len, word32 out[ 2 ], word32 const key[ 8 ])
{
	register word32 n1, n2; /* As named in the GOST */

	n1 =  0 ;
	n2 =  0 ;

	while (len--) {
		n1 ^= *in++;
		n2 = *in++;

		/* Instead of swapping halves, swap names each round */
		n2 ^= f(n1+key[ 0 ]);
		n1 ^= f(n2+key[ 1 ]);
		n2 ^= f(n1+key[ 2 ]);
		n1 ^= f(n2+key[ 3 ]);
		n2 ^= f(n1+key[ 4 ]);
		n1 ^= f(n2+key[ 5 ]);
		n2 ^= f(n1+key[ 6 ]);
		n1 ^= f(n2+key[ 7 ]);

		n2 ^= f(n1+key[ 0 ]);
		n1 ^= f(n2+key[ 1 ]);
		n2 ^= f(n1+key[ 2 ]);
		n1 ^= f(n2+key[ 3 ]);
		n2 ^= f(n1+key[ 4 ]);
		n1 ^= f(n2+key[ 5 ]);
		n2 ^= f(n1+key[ 6 ]);
		n1 ^= f(n2+key[ 7 ]);
	}

	out[ 0 ] = n1;
	out[ 1 ] = n2;
}

#ifdef TEST

#include <stdio.h>
#include <stdlib.h>

/* Designed to cope with 15-bit rand() implementations */
#define RAND32 ((word32)rand() <<  17  ^ (word32)rand() <<  9  ^ rand())

int
main(void)
{
	word32 key[ 8 ];
	word32 plain[ 2 ];
	word32 cipher[ 2 ];
	int i, j;

	kboxinit();

	printf("GOST 21847-89 test driver.\n");


	for (j =  0 ; j <  8 ; j++){
			key[j] = RAND32;
		plain[ 0 ] = RAND32;
		plain[ 1 ] = RAND32;
		printf("%3d\r", i);
		fflush(stdout);

		gostcrypt(plain, cipher, key);
		for (j =  0 ; j <  99 ; j++)
			gostcrypt(cipher, cipher, key);
		for (j =  0 ; j <  100 ; j++)
			gostdecrypt(cipher, cipher, key);

		if (plain[ 0 ] != cipher[ 0 ] || plain[ 1 ] != cipher[ 1 ]) {
			fprintf(stderr, "\nError! i = %d\n", i);
			return  1 ;
		}
	}
	
	printf("All tests passed.\n");
	return  0 ;
}

#endif /* TEST */

и

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
//			РЕЛІЗАЦІЯ АЛГОРИТМУ ШИФРУВАННЯ ДАНИХ ГОСТ 28147-89 
//			автор:
//			Геннадій Панасенко
//
//			сайт:
//			www.getsoft.com.ua
//
//			Пояснення
//
// m та s - молодша та старша частини блоку, що щифрується відповідно (об'явлені як глобальні змінні)
// Gm та Gs - шифргамми для молодшої та старшої частини блоку, що шифрується відповідно (об'явлені як глобальні змінні)
// password - пароль введений користувачем
// keymas[32] - набір ключів (int) (об'явлена як глобальна змінна)
// action - дія шифрування або розшифрування ("true" та "false" відповідно)
// data_block[2] - блок даних для передачи функції шифрування (об'явлена як глобальна змінна)
// ZamTab[1024] - перетворена таблиця замін (об'явлена як глобальна змінна)
// TObject *Sender - таблиця в розмірності 16 колонок на 8 строчок (1 колонка і 1 строчка фіксовані і використовуються
// для нумерації) обов'язково StringGrid 
//
// Порядок роботи функції:
// 1. Після введеня пароля і заповнення або вказання файла таблиці замін генерація масиву ключів
//      функцією "void GetKeyMas (AnsiString password, int keymas[32], bool action)", перетворення таблиці замін до
//      більш зручного вигляду функцією "char ConvertZamTab (TObject *Sender, char ZamTab[])".
// 2. Для зашифрування - читання по 4 символи і перетворення їх в числа функцією "int EnCodeString (char value[])".
// 3. Для розшифрування - читання необхідної кількості символів в змінну "char" довжиною 4 байта (4 символи. Не заповнені
//      позиції символів обнуляються) і перетворюються в строку функцією "AnsiString DeCodeString (int value)".
// 4. Безпосередньо шифрування функцією "int USE_GOST_28147 (int data_block[], int keymas[], char ZamTab[], bool action)".
 
char    ZamTab [ 1024 ];

int     data_block[ 2 ],
        keymas[ 32 ],
        Gm,
        Gs,
        m,
        s,
        key,
        oper;

//=======================================================================================

// Функція переведення прочитаних даних в число

int EnCodeString (char value[]); // Розмірність value = 4
int EnCodeString (char value[])
{
int result;
char znak;

for (int i =  0 ; i <  4 ; i++)
        {
        znak = value[i];
        asm
                {
                mov eax, result;
                shl eax,  8 ;
                mov al, znak;
                mov result, eax;
                }
        }

return result;
}

// Кінець функції переведення прочитаних даних в число

//=======================================================================================

// Функція переведення числа в дані

AnsiString DeCodeString (int value);
AnsiString DeCodeString (int value)
{
char result[ 4 ], znak;
AnsiString res;

for (int i =  3 ; i >=  0 ; i--)
        {
        asm
                {
                mov eax, value;
                mov znak, al;
                shr eax,  8 ;
                mov value, eax;
                }
        result[i] = znak;
        }

result[ 4 ] =  0 ;
res = (AnsiString)result;
return res;
}

// Кінець функції переведення числа в дані

//=======================================================================================

// Функція генерації шифргами та накладання її на дані

void CryptWithGamma ();
void CryptWithGamma ()
        {
        int Gamma, block;

        Gamma = Gs;
        block = s;
        asm
                {
                mov eax, Gamma;
                mov ebx, block;

                ror eax,  1 ;
                jnc end1;

                xor eax, 0x1010101;

                end1:
                xor ebx, eax;
                mov block, ebx;
                mov Gamma, eax;
                }
        Gs = Gamma;
        s = block;

        Gamma = Gm;
        block = m;

        asm
                {
                mov eax, Gamma;
                mov ebx, block;

                ror eax,  1 ;
                jnc end2;

                xor eax, 0x1010104;

                end2:
                xor ebx, eax;
                mov block, ebx;
                mov Gamma, eax;
                }
        Gm = Gamma;
        m = block;
        }

// Кінець функції генерації шифргами та накладання її на дані

//=======================================================================================

// Функція отримання масиву ключів

void GetKeyMas (AnsiString password, int keymas[ 32 ], bool action);
void GetKeyMas (AnsiString password, int keymas[ 32 ], bool action)
        {
        char keystr [ 32 ];
        int keycode = password.Length();
        strcpy (keystr, password.c_str());

        // Перетворення набраного пароля в 32 знакову комбінацію
        for (int i =  0 ; i < password.Length(); i++)
                {
                keycode = (keycode * int(keystr[i]))% 16777216 ;
                }

        for (int i = password.Length(); i <  32 ; i++)
                {          
                keystr[i] = keycode * i + i;
                }

        if (action == true) // Якщо зашифрування
                {
                keymas[ 0 ] = int(keystr[ 0 ]) * int(keystr[ 1 ]) * int(keystr[ 2 ]) * int(keystr[ 3 ]);
                keymas[ 1 ] = int(keystr[ 4 ]) * int(keystr[ 5 ]) * int(keystr[ 6 ]) * int(keystr[ 7 ]);
                keymas[ 2 ] = int(keystr[ 8 ]) * int(keystr[ 9 ]) * int(keystr[ 10 ]) * int(keystr[ 11 ]);
                keymas[ 3 ] = int(keystr[ 12 ]) * int(keystr[ 13 ]) * int(keystr[ 14 ]) * int(keystr[ 15 ]);
                keymas[ 4 ] = int(keystr[ 16 ]) * int(keystr[ 17 ]) * int(keystr[ 18 ]) * int(keystr[ 19 ]);
                keymas[ 5 ] = int(keystr[ 20 ]) * int(keystr[ 21 ]) * int(keystr[ 22 ]) * int(keystr[ 23 ]);
                keymas[ 6 ] = int(keystr[ 24 ]) * int(keystr[ 25 ]) * int(keystr[ 26 ]) * int(keystr[ 27 ]);
                keymas[ 7 ] = int(keystr[ 28 ]) * int(keystr[ 29 ]) * int(keystr[ 30 ]) * int(keystr[ 31 ]);
                keymas[ 8 ] = keymas[ 0 ];
                keymas[ 9 ] = keymas[ 1 ];
                keymas[ 10 ] = keymas[ 2 ];
                keymas[ 11 ] = keymas[ 3 ];
                keymas[ 12 ] = keymas[ 4 ];
                keymas[ 13 ] = keymas[ 5 ];
                keymas[ 14 ] = keymas[ 6 ];
                keymas[ 15 ] = keymas[ 7 ];
                keymas[ 16 ] = keymas[ 0 ];
                keymas[ 17 ] = keymas[ 1 ];
                keymas[ 18 ] = keymas[ 2 ];
                keymas[ 19 ] = keymas[ 3 ];
                keymas[ 20 ] = keymas[ 4 ];
                keymas[ 21 ] = keymas[ 5 ];
                keymas[ 22 ] = keymas[ 6 ];
                keymas[ 23 ] = keymas[ 7 ];
                keymas[ 24 ] = keymas[ 7 ];
                keymas[ 25 ] = keymas[ 6 ];
                keymas[ 26 ] = keymas[ 5 ];
                keymas[ 27 ] = keymas[ 4 ];
                keymas[ 28 ] = keymas[ 3 ];
                keymas[ 29 ] = keymas[ 2 ];
                keymas[ 30 ] = keymas[ 1 ];
                keymas[ 31 ] = keymas[ 0 ];
                }

        if (action == false) // Якщо розшифрування
                {
                keymas[ 0 ] = int(keystr[ 0 ]) * int(keystr[ 1 ]) * int(keystr[ 2 ]) * int(keystr[ 3 ]);
                keymas[ 1 ] = int(keystr[ 4 ]) * int(keystr[ 5 ]) * int(keystr[ 6 ]) * int(keystr[ 7 ]);
                keymas[ 2 ] = int(keystr[ 8 ]) * int(keystr[ 9 ]) * int(keystr[ 10 ]) * int(keystr[ 11 ]);
                keymas[ 3 ] = int(keystr[ 12 ]) * int(keystr[ 13 ]) * int(keystr[ 14 ]) * int(keystr[ 15 ]);
                keymas[ 4 ] = int(keystr[ 16 ]) * int(keystr[ 17 ]) * int(keystr[ 18 ]) * int(keystr[ 19 ]);
                keymas[ 5 ] = int(keystr[ 20 ]) * int(keystr[ 21 ]) * int(keystr[ 22 ]) * int(keystr[ 23 ]);
                keymas[ 6 ] = int(keystr[ 24 ]) * int(keystr[ 25 ]) * int(keystr[ 26 ]) * int(keystr[ 27 ]);
                keymas[ 7 ] = int(keystr[ 28 ]) * int(keystr[ 29 ]) * int(keystr[ 30 ]) * int(keystr[ 31 ]);
                keymas[ 8 ] = keymas[ 7 ];
                keymas[ 9 ] = keymas[ 6 ];
                keymas[ 10 ] = keymas[ 5 ];
                keymas[ 11 ] = keymas[ 4 ];
                keymas[ 12 ] = keymas[ 3 ];
                keymas[ 13 ] = keymas[ 2 ];
                keymas[ 14 ] = keymas[ 1 ];
                keymas[ 15 ] = keymas[ 0 ];
                keymas[ 16 ] = keymas[ 7 ];
                keymas[ 17 ] = keymas[ 6 ];
                keymas[ 18 ] = keymas[ 5 ];
                keymas[ 19 ] = keymas[ 4 ];
                keymas[ 20 ] = keymas[ 3 ];
                keymas[ 21 ] = keymas[ 2 ];
                keymas[ 22 ] = keymas[ 1 ];
                keymas[ 23 ] = keymas[ 0 ];
                keymas[ 24 ] = keymas[ 7 ];
                keymas[ 25 ] = keymas[ 6 ];
                keymas[ 26 ] = keymas[ 5 ];
                keymas[ 27 ] = keymas[ 4 ];
                keymas[ 28 ] = keymas[ 3 ];
                keymas[ 29 ] = keymas[ 2 ];
                keymas[ 30 ] = keymas[ 1 ];
                keymas[ 31 ] = keymas[ 0 ];
                }
        }

// Кінець функції отримання масиву ключів

//=======================================================================================

// Функція перетворення по ГОСТ

int USE_GOST_28147 (int data_block[], int keymas[], char ZamTab[], bool action);
int USE_GOST_28147 (int data_block[], int keymas[], char ZamTab[], bool action)
{
char tmp;
int ITEMP;

m = data_block[ 0 ];
s = data_block[ 1 ];

if (action == true)  // Якщо зашифрування
        {
        CryptWithGamma ();
        }

for (int i =  0 ; i <  32 ; i++)
        {
        int key = keymas[i];
        // Складання по модулю з ключем
        asm
                {
                mov eax, m;
                mov ecx, key;
                add eax, ecx;
                mov oper, eax;
                }

        // Таблиця замін
        for (int i =  0 ; i <  4 ; i++)
                {
                asm
                        {
                        mov eax, oper;
                        mov tmp, al;
                        }
                ITEMP = tmp*i;
                tmp = ZamTab [ITEMP];
                asm
                        {
                        mov eax, oper;
                        xchg al, tmp;

                        ror eax,  8 ;
                        mov oper, eax;
                        }
                }

        // Циклічний зсув на 11 біт ліворуч
        asm
                {
                mov eax, oper;
                rol eax,  11 ;

                // Побітове додавання отриманого значення і старшої половини блока

                mov ebx, s;
                xor eax, ebx;
                mov oper, eax;
                }

        if (i <  31 )
                {
                s = m;
                m = oper;
                }
        else
                {
                s = oper;
                }


        }

if (action == false)  // Якщо розшифрування
        {
        CryptWithGamma ();
        }

data_block[ 0 ] = m;
data_block[ 1 ] = s;

return *data_block;
}

// Кінець функції перетворення по ГОСТ

//=======================================================================================

// Функція перетворення таблиці замін в 8 бітний блок

char ConvertZamTab (TObject *Sender, char ZamTab[]);
char ConvertZamTab (TObject *Sender, char ZamTab[])
{
int count =  0 ;
TStringGrid *SG = dynamic_cast<TStringGrid*>(Sender);
for (int i =  1 ; i <= SG->RowCount -  2 ; )
        {
        for (int j =  1 ; j <=  16 ; j++)
                {
                for (int k =  1 ; k <=  16 ; k++)
                        {
                        ZamTab[count] = StrToInt(SG->Cells[j][i]) * StrToInt(SG->Cells[k][i +  1 ]);
                        count++;
                        }
                }
        i = i +  2 ;
        }
return *ZamTab;
}

// Кінець функції перетворення таблиці замін в 8 бітний блок

//=======================================================================================

Бедные те кто на трафике, мне вас жалко :))

Я немогу не с одним разобраться как использовать..

В первом какие-то непонятно зачем циклы
for (j = 0; j < 89; j++) gostcrypt(cipher, cipher, key);
for (j = 0; j < 90; j++) gostdecrypt(cipher, cipher, key);

Непонятно почему ключ key [8] , разве длинна больше быть неможет?
Непонятно почему cipher [2] разве больше быть неможет? :)


Во втором непонятно как инициализировать таблицу подстаноки. Также непонятно как вызывать..
Вообщем я очень прошу знающих, напишите плз для любого из этих алгоритмов какую-то обёртку вроде

char* Crypt (char* key, char* source)

и расшифрование агалогично. Одним словом - по проще как-то :) Уверен там несколько строчек кода...

P.S. Плз, не отправляйте в поиск и ботать гост, я только что оттуда.. пока нашел эти сырсы довольно много пришлось про гост этот перечитать :)
...
Рейтинг: 0 / 0
Пример использования ГОСТ 21847-89
    #34646122
PrevedMedved
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ботай гост, гугл тебе в руки, юзай поиск, а книжки читать - не царское дело?
...
Рейтинг: 0 / 0
Пример использования ГОСТ 21847-89
    #34646124
RUSYA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
До последнией строчки таки не асилил?
...
Рейтинг: 0 / 0
Пример использования ГОСТ 21847-89
    #34743359
teras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может и не актуально уже...
RUSYAВ первом какие-то непонятно зачем циклы
for (j = 0; j < 89; j++) gostcrypt(cipher, cipher, key);
for (j = 0; j < 90; j++) gostdecrypt(cipher, cipher, key); Это тест - сто раз шифруем, что раз дешифруем и сравниваем.

RUSYAНепонятно почему ключ key [8] , разве длинна больше быть неможет?
Непонятно почему cipher [2] разве больше быть неможет? :) Алгоритм использован в режиме ECB, то есть на оба вопроса ответ - нет, не может. Длина ключа - принципиально ограничена алгоритмом, длина шифруемого блока может изменяться при помощи режимов шифрования, например, OFB, CBC, COUNTER, и т.д. и т.п.

RUSYAВо втором непонятно как инициализировать таблицу подстаноки. Вообще, таблица подстановки не входит в ГОСТ, предполагается, что она выдается соответствующими органами (деятельность-то в России лицензируется). Возмите из первого, или сгенерируйте случайным образом. Вообще, при доступном режиме ECB, эта таблица вычисляется за день. То есть информация не очень-то и секретна.

RUSYAВообщем я очень прошу знающих, напишите плз для любого из этих алгоритмов какую-то обёртку вроде А там уже есть - gostofb и gostcfb*. По стандарту положено разбивать сообщения на 8-байтовые блоки и дополнять последний блок нулями до 8 байт.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Пример использования ГОСТ 21847-89
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]