Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

gost.cpp

00001 #include "pch.h" 00002 #include "gost.h" 00003 #include "misc.h" 00004 00005 NAMESPACE_BEGIN(CryptoPP) 00006 00007 // these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 00008 const byte GOST::Base::sBox[8][16]={ 00009 {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3}, 00010 {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9}, 00011 {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11}, 00012 {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3}, 00013 {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2}, 00014 {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14}, 00015 {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12}, 00016 {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12}}; 00017 00018 /* // these are the S-boxes given in the GOST source code listing in Applied 00019 // Cryptography 2nd Ed., p. 644. they appear to be from the DES S-boxes 00020 {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, 00021 { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, 00022 {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, 00023 { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, 00024 { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, 00025 {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, 00026 {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, 00027 {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }}; 00028 */ 00029 00030 bool GOST::Base::sTableCalculated = false; 00031 word32 GOST::Base::sTable[4][256]; 00032 00033 void GOST::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length) 00034 { 00035 AssertValidKeyLength(length); 00036 00037 PrecalculateSTable(); 00038 00039 GetUserKey(LITTLE_ENDIAN_ORDER, key.begin(), 8, userKey, KEYLENGTH); 00040 } 00041 00042 void GOST::Base::PrecalculateSTable() 00043 { 00044 if (!sTableCalculated) 00045 { 00046 for (unsigned i = 0; i < 4; i++) 00047 for (unsigned j = 0; j < 256; j++) 00048 { 00049 word32 temp = sBox[2*i][j%16] | (sBox[2*i+1][j/16] << 4); 00050 sTable[i][j] = rotlMod(temp, 11+8*i); 00051 } 00052 00053 sTableCalculated=true; 00054 } 00055 } 00056 00057 #define f(x) ( t=x, \ 00058 sTable[3][GETBYTE(t, 3)] ^ sTable[2][GETBYTE(t, 2)] \ 00059 ^ sTable[1][GETBYTE(t, 1)] ^ sTable[0][GETBYTE(t, 0)] ) 00060 00061 typedef BlockGetAndPut<word32, LittleEndian> Block; 00062 00063 void GOST::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 00064 { 00065 word32 n1, n2, t; 00066 00067 Block::Get(inBlock)(n1)(n2); 00068 00069 for (unsigned int i=0; i<3; i++) 00070 { 00071 n2 ^= f(n1+key[0]); 00072 n1 ^= f(n2+key[1]); 00073 n2 ^= f(n1+key[2]); 00074 n1 ^= f(n2+key[3]); 00075 n2 ^= f(n1+key[4]); 00076 n1 ^= f(n2+key[5]); 00077 n2 ^= f(n1+key[6]); 00078 n1 ^= f(n2+key[7]); 00079 } 00080 00081 n2 ^= f(n1+key[7]); 00082 n1 ^= f(n2+key[6]); 00083 n2 ^= f(n1+key[5]); 00084 n1 ^= f(n2+key[4]); 00085 n2 ^= f(n1+key[3]); 00086 n1 ^= f(n2+key[2]); 00087 n2 ^= f(n1+key[1]); 00088 n1 ^= f(n2+key[0]); 00089 00090 Block::Put(xorBlock, outBlock)(n2)(n1); 00091 } 00092 00093 void GOST::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 00094 { 00095 word32 n1, n2, t; 00096 00097 Block::Get(inBlock)(n1)(n2); 00098 00099 n2 ^= f(n1+key[0]); 00100 n1 ^= f(n2+key[1]); 00101 n2 ^= f(n1+key[2]); 00102 n1 ^= f(n2+key[3]); 00103 n2 ^= f(n1+key[4]); 00104 n1 ^= f(n2+key[5]); 00105 n2 ^= f(n1+key[6]); 00106 n1 ^= f(n2+key[7]); 00107 00108 for (unsigned int i=0; i<3; i++) 00109 { 00110 n2 ^= f(n1+key[7]); 00111 n1 ^= f(n2+key[6]); 00112 n2 ^= f(n1+key[5]); 00113 n1 ^= f(n2+key[4]); 00114 n2 ^= f(n1+key[3]); 00115 n1 ^= f(n2+key[2]); 00116 n2 ^= f(n1+key[1]); 00117 n1 ^= f(n2+key[0]); 00118 } 00119 00120 Block::Put(xorBlock, outBlock)(n2)(n1); 00121 } 00122 00123 NAMESPACE_END

Generated on Wed Jul 21 19:15:26 2004 for Crypto++ by doxygen 1.3.7-20040704