From: vf@usb.gf.unity.net (Vadim Fedukovich) Newsgroups: relcom.comp.security Subject: GOST algorithm src Date: 19 May 1997 10:49:57 -0000 Organization: usb Message-ID: <5lpb8l$ah4@usb.gf.unity.net> -----BEGIN PGP SIGNED MESSAGE----- Коллеги, ниже представлена реализация, которая может использоваться для легальной криптографии. Представлен симметричный алгоритм GOST, который ничуть не хуже IDEA и имеет больше шансов получить необходимую для легального использования в России оценку ФАПСИ; не-российские пользователи тоже могут воспользоваться опубликованным (тем же самым!) алгоритмом. В книге "Applied Cryptography" приводится реализация алгоритма, при этом делаются ссылки на следующие документы: 1. GOST 28147-89, "Cryptographic Protection for Data Processing Systems" 2. GOST R 34.11-94 "...Hashing function" Мне хотелось бы знать, дает ли опубликованная реализация алгоритма тот же cipherext (то есть, результат) что и сертифицируемая реализация. Для того, чтобы можно было сравнить результаты (ciphertext'ы), приводится также и результат использования опубликованного в этом msg алгоритма. В случае получения заключения об идентичности результатов алгоритм можно использовать outside для inter-operability с легально сертифицированными в России крипто-сервисами. Кстати, чисто формально, ключ длиной 256 бит для симметричного алгоритма - это серьезно! Более длинные ключи использует только (из известных мне) алгоритм crab, 1024 бит, но он мало известен. успехов, Вадим Федюкович. p.s. На всякий случай добавлю: - эта публикация не нарушает законов Украины, - использует только публично доступную информацию, - у меня есть разрешение автора книги на публикацию. /* ------------------------- cut here ----------------------------- */ typedef unsigned long u4; typedef unsigned char uch; typedef struct { u4 long k[8]; char k87[256], k65[256], k43[256], k21[256]; } gost_ctx; void gost_enc( gost_ctx *, u4 *, int ); void gost_dec( gost_ctx *, u4 *, int ); void gost_key( gost_ctx *, u4 * ); void gost_init( gost_ctx * ); void gost_destroy( gost_ctx * ); char data[512] = "Novodachnaja. 50 years anniversary 7890"; /* great college */ /* GOST (exUSSR) as implemented frm * "Applied Cryptography" book by Bruce Schneier, second ed. * Date: 9 May 1997 */ void kboxinit( gost_ctx * key ) { int i; uch k8[16] = { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }; uch k7[16] = { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }; uch k6[16] = { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }; uch k5[16] = { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }; uch k4[16] = { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }; uch k3[16] = { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }; uch k2[16] = { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }; uch k1[16] = { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }; for( i = 0; i < 256; i++ ) { key -> k87[i] = k8[i >> 4] << 4 | k7[i & 15]; key -> k65[i] = k6[i >> 4] << 4 | k5[i & 15]; key -> k43[i] = k4[i >> 4] << 4 | k3[i & 15]; key -> k21[i] = k2[i >> 4] << 4 | k1[i & 15]; } } static u4 gostf( gost_ctx * key, u4 x) { x = key -> k87[ x >> 24 & 255] << 24 | key -> k65[ x >> 16 & 255 ] << 16 | key -> k43[ x >> 8 & 255] << 8 | key -> k21[ x & 255 ] ; return x << 11 | x >> (32 - 11); } void gostcrypt( gost_ctx * key, u4 * d ) { unsigned long n1, n2; n1 = d[0]; n2 = d[1]; n2 ^= gostf(key, n1 + key -> k[0]); n1 ^= gostf(key, n2 + key -> k[1]); n2 ^= gostf(key, n1 + key -> k[2]); n1 ^= gostf(key, n2 + key -> k[3]); n2 ^= gostf(key, n1 + key -> k[4]); n1 ^= gostf(key, n2 + key -> k[5]); n2 ^= gostf(key, n1 + key -> k[6]); n1 ^= gostf(key, n2 + key -> k[7]); n2 ^= gostf(key, n1 + key -> k[0]); n1 ^= gostf(key, n2 + key -> k[1]); n2 ^= gostf(key, n1 + key -> k[2]); n1 ^= gostf(key, n2 + key -> k[3]); n2 ^= gostf(key, n1 + key -> k[4]); n1 ^= gostf(key, n2 + key -> k[5]); n2 ^= gostf(key, n1 + key -> k[6]); n1 ^= gostf(key, n2 + key -> k[7]); n2 ^= gostf(key, n1 + key -> k[0]); n1 ^= gostf(key, n2 + key -> k[1]); n2 ^= gostf(key, n1 + key -> k[2]); n1 ^= gostf(key, n2 + key -> k[3]); n2 ^= gostf(key, n1 + key -> k[4]); n1 ^= gostf(key, n2 + key -> k[5]); n2 ^= gostf(key, n1 + key -> k[6]); n1 ^= gostf(key, n2 + key -> k[7]); n2 ^= gostf(key, n1 + key -> k[7]); n1 ^= gostf(key, n2 + key -> k[6]); n2 ^= gostf(key, n1 + key -> k[5]); n1 ^= gostf(key, n2 + key -> k[4]); n2 ^= gostf(key, n1 + key -> k[3]); n1 ^= gostf(key, n2 + key -> k[2]); n2 ^= gostf(key, n1 + key -> k[1]); n1 ^= gostf(key, n2 + key -> k[0]); d[0]=n2; d[1]=n1; } void gostdecrypt( gost_ctx * key, u4 * d ) { unsigned long n1, n2; n1 = d[0]; n2 = d[1]; n2 ^= gostf(key, n1 + key -> k[0]); n1 ^= gostf(key, n2 + key -> k[1]); n2 ^= gostf(key, n1 + key -> k[2]); n1 ^= gostf(key, n2 + key -> k[3]); n2 ^= gostf(key, n1 + key -> k[4]); n1 ^= gostf(key, n2 + key -> k[5]); n2 ^= gostf(key, n1 + key -> k[6]); n1 ^= gostf(key, n2 + key -> k[7]); n2 ^= gostf(key, n1 + key -> k[7]); n1 ^= gostf(key, n2 + key -> k[6]); n2 ^= gostf(key, n1 + key -> k[5]); n1 ^= gostf(key, n2 + key -> k[4]); n2 ^= gostf(key, n1 + key -> k[3]); n1 ^= gostf(key, n2 + key -> k[2]); n2 ^= gostf(key, n1 + key -> k[1]); n1 ^= gostf(key, n2 + key -> k[0]); n2 ^= gostf(key, n1 + key -> k[7]); n1 ^= gostf(key, n2 + key -> k[6]); n2 ^= gostf(key, n1 + key -> k[5]); n1 ^= gostf(key, n2 + key -> k[4]); n2 ^= gostf(key, n1 + key -> k[3]); n1 ^= gostf(key, n2 + key -> k[2]); n2 ^= gostf(key, n1 + key -> k[1]); n1 ^= gostf(key, n2 + key -> k[0]); n2 ^= gostf(key, n1 + key -> k[7]); n1 ^= gostf(key, n2 + key -> k[6]); n2 ^= gostf(key, n1 + key -> k[5]); n1 ^= gostf(key, n2 + key -> k[4]); n2 ^= gostf(key, n1 + key -> k[3]); n1 ^= gostf(key, n2 + key -> k[2]); n2 ^= gostf(key, n1 + key -> k[1]); n1 ^= gostf(key, n2 + key -> k[0]); d[0]=n2; d[1]=n1; } void gost_enc( gost_ctx * c, u4 * d, int blocks ) { int i; for( i = 0; i < blocks; i++ ) { gostcrypt( c, d ); d += 2; } } void gost_dec( gost_ctx * c, u4 * d, int blocks ) { int i; for( i = 0; i < blocks; i++ ) { gostdecrypt( c, d ); d += 2; } } void gost_key( gost_ctx * c, u4 * k ) { int i; for( i = 0; i < 8; i++ ) c -> k[i] = k[i]; } void gost_init( gost_ctx * c ) { kboxinit( c ); } void gost_destroy( gost_ctx * c ) { int i; for( i = 0; i < 8; i++ ) c -> k[i] = 0; } #include void main( void ) { gost_ctx gc; u4 k[8]; int i; gost_init( & gc ); for( i = 0; i < 8; i ++ ) k[i]=i; gost_key( & gc, k ); printf("To crypt (1st block): %08lx %08lx\n", *(u4 *)data, *(u4 *)(data + 4)); gostcrypt( &gc, (u4 *) data ); printf("Encrypted of above: %08lx %08lx\n", *(u4 *)data, *(u4 *)(data + 4)); gostdecrypt( &gc, (u4 *) data ); printf("Decrypted: %08lx %08lx\n", *(u4 *)data, *(u4 *)(data + 4)); for( i = 0; i < 5; i ++ ) printf( " %08lx %08lx.", *(u4 *)(data + i * 8), *(u4 *)(data + i * 8 + 4 )); printf( " - original\n" ); gost_enc( &gc, (u4 *)data, 5 ); /* 5 blocks u4 */ for( i = 0; i < 5; i ++ ) printf( " %08lx %08lx.", *(u4 *)(data + i * 8), *(u4 *)(data + i * 8 + 4 )); printf( " - encrypted\n" ); gost_dec( &gc, (u4 *)data, 5 ); for( i = 0; i < 5; i ++ ) printf( " %08lx %08lx.", *(u4 *)(data + i * 8), *(u4 *)(data + i * 8 + 4 )); printf( " - decrypted\n" ); gost_destroy( & gc ); } /* ------------------------- cut here ----------------------------- */ To crypt (1st block): 6f766f4e 68636164 Encrypted of above: 1cfeebe3 baad9d5f Decrypted: 6f766f4e 68636164 6f766f4e 68636164. 616a616e 3520202e. 65792030 20737261. 696e6e61 73726576. 20797261 30393837. - original 1cfeebe3 baad9d5f. 3522d82e 6e94196d. 20733261 657be830. 658d8d74 21ee5293. 30394837 6de14263. - encrypted 6f766f4e 68636164. 616a616e 3520202e. 65792030 20737261. 696e6e61 73726576. 20797261 30393837. - decrypted /* ------------------------- cut here ----------------------------- */ -----BEGIN PGP SIGNATURE----- Version: 2.6.3i Charset: koi8 iQCVAwUBM3+NoRqNnVyvgmKRAQEenQQAglvQw8Yxp0ibrpwJQdC1eicBWKx7X/2d MaywLsE/L5Y/1K0weVtpCrQju0y66PAkLoMkXUn3d0VRp+bqPISm7QqGSHDtGyvz V9HtV2V4+DiZT0RIbcEXFKNKM8MgcUImzI56wAMXV2jaYjDpHtaWkbSDB7SpwauO OSOLRWMEVEs= =svkU -----END PGP SIGNATURE-----