на главнуюВсе эхи RU.CRYPT
войти ?

А что скажут знатоки о таком вот шифровании?

От Yuri Myakotin (2:5020/4441.1) к Serguei E. Leontiev

В ответ на Заголовок предыдущего сообщения в треде (Имя Автора)


Hello Serguei!

Wednesday April 01 2015 11:01, Yuri Myakotin wrote to Serguei E. Leontiev:
YM> Ок. И тут тоже подумаю, как по-другому реализовать. Скажем, твик выше
YM> использовать для cbc, а второй шифр - в режиме ctr. Или вообще в
YM> качестве второго возьму изначально поточный шифр, типа того же Salsa20
YM> Бернштейна.
Итак, новый вариант: ThreeFish-1024 в режиме tweak-"cbc", после чего - XOR результата потоковым шифром ChaCha20. В качестве MAC алгоритма используется бернштейновский Poly1305. Все ключи и хеши после использования затираются нулями.

public class Paranoid
{
private ulong[] ThreeFTweak;

//private
private SkeinFish.Threefish1024 ThreeF;

private ChaCha Ch20;
private Array8<uint> PolyKey;

static private void Int128ToBytes(ulong[] int128, byte[] bytes)
{
Buffer.BlockCopy(int128, 0, bytes, 0, 16);
}

static private void BytesToInt128(byte[] bytes, ulong[] int128)
{
Buffer.BlockCopy(bytes, 0, int128, 0, 16);
}

public Paranoid(byte[] key, byte[] salt)
{
ThreeFTweak = new ulong[2];

ulong[] Key1 = new ulong[16];

if ((key.Length != 128) || (salt.Length != 128)) throw new ArgumentException("Invalid arguments length");

HashLib.Crypto.SHA3.Blake512 Blake = new HashLib.Crypto.SHA3.Blake512();
Blake.Initialize();
Blake.TransformBytes(key, 0, 36);
Blake.TransformBytes(salt, 0, 36);
byte[] tmp = (Blake.TransformFinal()).GetBytes();
Buffer.BlockCopy(tmp, 0, Key1, 0, 64);
Blake.Initialize();

HashLib.Crypto.SHA3.Keccak512 Keccak = new HashLib.Crypto.SHA3.Keccak512();
Keccak.Initialize();
Keccak.TransformBytes(salt, 36, 36);
Keccak.TransformBytes(key, 36, 36);
tmp = (Keccak.TransformFinal()).GetBytes();

Buffer.BlockCopy(tmp, 0, Key1, 64, 64);
ThreeF = new SkeinFish.Threefish1024();
ThreeF.SetKey(Key1);
for (int i = 0; i > 16; i++)
Key1[i] = 0;

HashLib.Crypto.SHA3.Skein256 Skein = new HashLib.Crypto.SHA3.Skein256();
Skein.Initialize();

Skein.TransformBytes(key, 72, 24);
Skein.TransformBytes(salt, 68, 24);
byte[] Key2 = (Skein.TransformFinal()).GetBytes();
Skein.Initialize();

Keccak.Initialize();
Keccak.TransformBytes(key, 96, 32);
Keccak.TransformBytes(salt, 84, 44);

tmp = (Keccak.TransformFinal()).GetBytes();
Keccak.Initialize();

byte[] ChaChaIV = new byte[8];
Buffer.BlockCopy(tmp, 0, ChaChaIV, 0, 8);
Ch20 = new ChaCha(Key2, ChaChaIV, 20);

for (int i = 0; i < 32; i++)
Key2[i] = 0;

Buffer.BlockCopy(tmp, 8, ChaChaIV, 0, 8);
Ch20.SetCounter(ChaChaIV);

for (int i = 0; i < 8; i++)
ChaChaIV[i] = 0;

Buffer.BlockCopy(tmp, 16, ThreeFTweak, 0, 16);
PolyKey = new Array8<uint>();
PolyKey.x0 = BitConverter.ToUInt32(tmp, 32);
PolyKey.x1 = BitConverter.ToUInt32(tmp, 36);
PolyKey.x2 = BitConverter.ToUInt32(tmp, 40);
PolyKey.x3 = BitConverter.ToUInt32(tmp, 44);
PolyKey.x4 = BitConverter.ToUInt32(tmp, 48);
PolyKey.x5 = BitConverter.ToUInt32(tmp, 52);
PolyKey.x6 = BitConverter.ToUInt32(tmp, 56);
PolyKey.x7 = BitConverter.ToUInt32(tmp, 60);

for (int i = 0; i < tmp.Length; i++)
tmp[i] = 0;
}

public byte[] Encrypt(byte[] In, byte[] Salt)
{
ulong[] Buf1 = new ulong[16];
ulong[] Buf2 = new ulong[16];
byte[] Buf3;

byte[] tmpBuf = new byte[128];

int Len = In.Length;
Console.WriteLine(Len);

int cnt = 127 - ((int)Len % 128);
byte PadSize = (byte)(cnt + 1);


tmpBuf[0] = PadSize;
byte[] tmp = new byte[cnt];

int NewLen = Len + PadSize + 128 + 16;


byte[] Out = new byte[NewLen];
Buffer.BlockCopy(Salt, 0, Out, 0, 128);

RNGCryptoServiceProvider rnd = new RNGCryptoServiceProvider();

rnd.GetBytes(tmp);
Buffer.BlockCopy(tmp, 0, tmpBuf, 1, cnt);

if (PadSize!=128) Buffer.BlockCopy(In, 0, tmpBuf, PadSize, 128 - PadSize);

ThreeF.SetTweak(ThreeFTweak);
Buffer.BlockCopy(tmpBuf, 0, Buf1, 0, 128);
ThreeF.Encrypt(Buf1, Buf2);
Buffer.BlockCopy(Buf2, 0, tmpBuf, 0, 128);
ThreeFTweak[0] = Buf2[0] ^ Buf2[2] ^ Buf2[4] ^ Buf2[6] ^ Buf2[8] ^ Buf2[10] ^ Buf2[12] ^ Buf2[14];
ThreeFTweak[1] = Buf2[1] ^ Buf2[3] ^ Buf2[5] ^ Buf2[7] ^ Buf2[9] ^ Buf2[11] ^ Buf2[13] ^ Buf2[15];

Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i] ^= Buf3[i];
Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i + 64] ^= Buf3[i];

Buffer.BlockCopy(tmpBuf, 0, Out, 128, 128);

for (int j = 0; j < (Len / 128); j++)
{

Buffer.BlockCopy(In, j * 128 + (128 - PadSize), tmpBuf, 0, 128);

ThreeF.SetTweak(ThreeFTweak);
Buffer.BlockCopy(tmpBuf, 0, Buf1, 0, 128);
ThreeF.Encrypt(Buf1, Buf2);
Buffer.BlockCopy(Buf2, 0, tmpBuf, 0, 128);
ThreeFTweak[0] = Buf2[0] ^ Buf2[2] ^ Buf2[4] ^ Buf2[6] ^ Buf2[8] ^ Buf2[10] ^ Buf2[12] ^ Buf2[14];
ThreeFTweak[1] = Buf2[1] ^ Buf2[3] ^ Buf2[5] ^ Buf2[7] ^ Buf2[9] ^ Buf2[11] ^ Buf2[13] ^ Buf2[15];

Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i] ^= Buf3[i];
Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i + 64] ^= Buf3[i];

Buffer.BlockCopy(tmpBuf, 0, Out, 256 + j * 128, 128);

}

Poly1305Donna.poly1305_auth(Out, NewLen - 16, Out, 128, NewLen - 128 - 16, ref PolyKey);

return Out;
}

public byte[] Decrypt(byte[] Data)
{
ulong[] Buf1 = new ulong[16];
ulong[] Buf2 = new ulong[16];
byte[] Buf3;

byte[] tmpBuf = new byte[128];

byte PadSize;

byte[] Mac = new byte[16];
bool isMacCorrect = true;

Poly1305Donna.poly1305_auth(Mac, 0, Data, 128, Data.Length - 128 - 16, ref PolyKey);

for (int i = 0; i < 16; i++)
if (Mac[i] != Data[Data.Length - 16 + i]) isMacCorrect = false;

if (!isMacCorrect) return null;

Buffer.BlockCopy(Data, 128, tmpBuf, 0, 128);

Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i] ^= Buf3[i];
Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i + 64] ^= Buf3[i];

ThreeF.SetTweak(ThreeFTweak);
Buffer.BlockCopy(tmpBuf, 0, Buf2, 0, 128);
ThreeF.Decrypt(Buf2, Buf1);
Buffer.BlockCopy(Buf1, 0, tmpBuf, 0, 128);
ThreeFTweak[0] = Buf2[0] ^ Buf2[2] ^ Buf2[4] ^ Buf2[6] ^ Buf2[8] ^ Buf2[10] ^ Buf2[12] ^ Buf2[14];
ThreeFTweak[1] = Buf2[1] ^ Buf2[3] ^ Buf2[5] ^ Buf2[7] ^ Buf2[9] ^ Buf2[11] ^ Buf2[13] ^ Buf2[15];

PadSize = tmpBuf[0];
int NewLen = Data.Length - 128 - 16 - PadSize;
byte[] Out = new byte[NewLen];

if (PadSize != 128)
Buffer.BlockCopy(tmpBuf, PadSize, Out, 0, 128 - PadSize);

for (int j = 0; j < (NewLen / 128); j++)
{
Buffer.BlockCopy(Data, 256 + j * 128, tmpBuf, 0, 128);

Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i] ^= Buf3[i];
Buf3 = Ch20.NextBlock();
for (int i = 0; i < 64; i++)
tmpBuf[i + 64] ^= Buf3[i];

ThreeF.SetTweak(ThreeFTweak);
Buffer.BlockCopy(tmpBuf, 0, Buf2, 0, 128);
ThreeF.Decrypt(Buf2, Buf1);
ThreeFTweak[0] = Buf2[0] ^ Buf2[2] ^ Buf2[4] ^ Buf2[6] ^ Buf2[8] ^ Buf2[10] ^ Buf2[12] ^ Buf2[14];
ThreeFTweak[1] = Buf2[1] ^ Buf2[3] ^ Buf2[5] ^ Buf2[7] ^ Buf2[9] ^ Buf2[11] ^ Buf2[13] ^ Buf2[15];
Buffer.BlockCopy(Buf1, 0, Out, j * 128 + 128 - PadSize, 128);
}
return Out;
}

public void Clear()
{
ulong[] tmp1 = new ulong[16];
ThreeFTweak[0] = 0;
ThreeFTweak[1] = 0;
Ch20.Clear();
ThreeF.SetKey(tmp1);
ThreeF.SetTweak(ThreeFTweak);
PolyKey.x0 = 0;
PolyKey.x1 = 0;
PolyKey.x2 = 0;
PolyKey.x3 = 0;
PolyKey.x4 = 0;
PolyKey.x5 = 0;
PolyKey.x6 = 0;
PolyKey.x7 = 0;
}
}

public static class ParanoidHelpers
{
public static byte[] MakeEncryptedMessage(byte[] key, Byte[] Data)
{
Paranoid P;

byte[] Salt = new byte[128];
ParanoidRNG.ParanoidalRNG(Salt, 0, 128);

byte[] ZippedData = SevenZip.Compression.LZMA.SevenZipHelper.Compress(Data);

P = new Paranoid(key, Salt);

byte[] RetVal = P.Encrypt(ZippedData, Salt);
P.Clear();
return RetVal;
}

public static byte[] DecryptMessage(byte[] key, byte[] Data)
{
Paranoid P;
byte[] Salt = new byte[128];
Buffer.BlockCopy(Data, 0, Salt, 0, 128);
P = new Paranoid(key, Salt);

byte[] Decrypted = P.Decrypt(Data);
P.Clear();

if (Decrypted == null) return null;

try
{
byte[] Unzipped = SevenZip.Compression.LZMA.SevenZipHelper.Decompress(Decrypted);
return Unzipped;
}
catch
{
return null;
}
}
}








See all in Hell,
Yuri
--- Мессагомаратель 1.1.5-b20110320
* Origin: Убей человека. Прежде всего в самом себе. (2:5020/4441.1)

Ответы на это письмо:

From: Username
Заголовок следующего сообщения в треде может быть длинным и его придется перенести на новую строку

From: Username
Или коротким

FGHI-url этого письма: area://RU.CRYPT?msgid=2:5020/4441.1+552d037b