(Camellia): added key generation methods.

This commit is contained in:
morkt 2016-11-15 10:16:15 +04:00
parent 2bfeaf65be
commit 12cfdd289e

View File

@ -33,6 +33,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
using System; using System;
using System.Text;
using GameRes.Utility;
namespace GameRes.Cryptography namespace GameRes.Cryptography
{ {
@ -45,6 +47,93 @@ namespace GameRes.Cryptography
m_key = key; m_key = key;
} }
public Camellia (byte[] key)
{
m_key = GenerateKey (key);
}
public static uint[] GenerateKey (string passphrase)
{
int length = Math.Min (passphrase.Length, 16);
var key = new byte[16];
Encoding.UTF8.GetBytes (passphrase, 0, length, key, 0);
return GenerateKey (key);
}
static uint[] GenerateKey (byte[] key)
{
if (key.Length != 16)
throw new ApplicationException ("[Camellia] Invalid key length.");
uint s0, s1, s2, s3;
var k = new uint[52];
k[48] = s0 = BigEndian.ToUInt32 (key, 0);
k[49] = s1 = BigEndian.ToUInt32 (key, 4);
k[50] = s2 = BigEndian.ToUInt32 (key, 8);
k[51] = s3 = BigEndian.ToUInt32 (key, 12);
/* Use the Feistel routine to scramble the key material */
Feistel (s0, s1, ref s2, ref s3, 0);
Feistel (s2, s3, ref s0, ref s1, 2);
s0 ^= k[48]; s1 ^= k[49]; s2 ^= k[50]; s3 ^= k[51];
Feistel (s0, s1, ref s2, ref s3, 4);
Feistel (s2, s3, ref s0, ref s1, 6);
/* Fill the keyTable. Requires many block rotations. */
k[44] = s0; k[45] = s1; k[46] = s2; k[47] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 15); /* KA <<< 15 */
k[36] = s0; k[37] = s1; k[38] = s2; k[39] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 15); /* KA <<< 30 */
k[32] = s0; k[33] = s1; k[34] = s2; k[35] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 15); /* KA <<< 45 */
k[24] = s0; k[25] = s1;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 15); /* KA <<< 60 */
k[20] = s0; k[21] = s1; k[22] = s2; k[23] = s3;
RotLeft128 (ref s1, ref s2, ref s3, ref s0, 2); /* KA <<< 94 */
k[ 8] = s1; k[ 9] = s2; k[10] = s3; k[11] = s0;
RotLeft128 (ref s1, ref s2, ref s3, ref s0, 17); /* KA <<<111 */
k[ 0] = s1; k[ 1] = s2; k[ 2] = s3; k[ 3] = s0;
s0 = k[48]; s1 = k[49]; s2 = k[50]; s3 = k[51];
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 15); /* KL <<< 15 */
k[40] = s0; k[41] = s1; k[42] = s2; k[43] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 30); /* KL <<< 45 */
k[28] = s0; k[29] = s1; k[30] = s2; k[31] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 15); /* KL <<< 60 */
k[26] = s2; k[27] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 17); /* KL <<< 77 */
k[16] = s0; k[17] = s1; k[18] = s2; k[19] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 17); /* KL <<< 94 */
k[12] = s0; k[13] = s1; k[14] = s2; k[15] = s3;
RotLeft128 (ref s0, ref s1, ref s2, ref s3, 17); /* KL <<<111 */
k[ 4] = s0; k[ 5] = s1; k[ 6] = s2; k[ 7] = s3;
return k;
}
static void Feistel (uint s0, uint s1, ref uint s2, ref uint s3, int k)
{
uint t0 = s0 ^ SIGMA[k];
uint t1 = s1 ^ SIGMA[k+1];
uint t2 = SBOX1_1110[t1 & 0xFF] ^ SBOX4_4404[(t1 >> 8) & 0xFF];
uint t3 = SBOX4_4404[t0 & 0xFF] ^ SBOX3_3033[(t0 >> 8) & 0xFF]
^ SBOX2_0222[(t0 >> 16) & 0xFF] ^ SBOX1_1110[t0 >> 24];
t2 ^= t3;
t3 = Binary.RotR (t3, 8);
t2 ^= SBOX3_3033[(t1 >> 16) & 0xFF] ^ SBOX2_0222[t1 >> 24];
s3 ^= t3 ^ t2;
s2 ^= t2;
}
static void RotLeft128 (ref uint s0, ref uint s1, ref uint s2, ref uint s3, int n)
{
uint t0 = s0 >> (32 - n);
s0 = s0 << n | s1 >> (32 - n);
s1 = s1 << n | s2 >> (32 - n);
s2 = s2 << n | s3 >> (32 - n);
s3 = s3 << n | t0;
}
public uint[] Key public uint[] Key
{ {
get { return m_key; } get { return m_key; }
@ -313,5 +402,10 @@ namespace GameRes.Cryptography
0x07070007, 0x55550055, 0xEEEE00EE, 0x0A0A000A, 0x49490049, 0x68680068, 0x38380038, 0xA4A400A4, 0x07070007, 0x55550055, 0xEEEE00EE, 0x0A0A000A, 0x49490049, 0x68680068, 0x38380038, 0xA4A400A4,
0x28280028, 0x7B7B007B, 0xC9C900C9, 0xC1C100C1, 0xE3E300E3, 0xF4F400F4, 0xC7C700C7, 0x9E9E009E, 0x28280028, 0x7B7B007B, 0xC9C900C9, 0xC1C100C1, 0xE3E300E3, 0xF4F400F4, 0xC7C700C7, 0x9E9E009E,
}; };
static readonly uint[] SIGMA = {
0xA09E667F, 0x3BCC908B, 0xB67AE858, 0x4CAA73B2, 0xC6EF372F, 0xE94F82BE,
0x54FF53A5, 0xF1D36F1C, 0x10E527FA, 0xDE682D1D, 0xB05688C2, 0xB3E6C1FD
};
} }
} }