diff --git a/skyscraper8.sln.DotSettings.user b/skyscraper8.sln.DotSettings.user index 8c7cd78..883ca52 100644 --- a/skyscraper8.sln.DotSettings.user +++ b/skyscraper8.sln.DotSettings.user @@ -39,17 +39,17 @@ <Assembly Path="/home/schiemas/.nuget/packages/allure.net.commons/2.14.1/lib/netstandard2.0/Allure.Net.Commons.dll" /> </AssemblyExplorer> /home/schiemas/.cache/JetBrains/Rider2025.1/resharper-host/temp/Rider/vAny/CoverageData/_skyscraper8.1808907683/Snapshot/snapshot.utdcvr - <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;skyscraper8.Tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <And> - <Namespace>skyscraper8.Tests</Namespace> - <Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="&lt;skyscraper8.Tests&gt;" /> - </And> + <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;skyscraper8.Tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <And> + <Namespace>skyscraper8.Tests</Namespace> + <Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&lt;skyscraper8.Tests&gt;" /> + </And> </SessionState> - <SessionState ContinuousTestingMode="0" IsActive="True" Name="Continuous Testing" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="&lt;skyscraper8.Tests&gt;" /> + <SessionState ContinuousTestingMode="0" IsActive="True" Name="Continuous Testing" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&lt;skyscraper8.Tests&gt;" /> </SessionState> - <SessionState ContinuousTestingMode="0" Name="All tests from &lt;skyscraper8.Tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="/home/schiemas/RiderProjects/skyscraper8/skyscraper8.Tests" Presentation="&lt;skyscraper8.Tests&gt;" /> + <SessionState ContinuousTestingMode="0" Name="All tests from &lt;skyscraper8.Tests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> + <Project Location="\home\schiemas\RiderProjects\skyscraper8\skyscraper8.Tests" Presentation="&lt;skyscraper8.Tests&gt;" /> </SessionState> diff --git a/skyscraper8/Skyscraper/Security/Cryptography/DvbCsa2.cs b/skyscraper8/Skyscraper/Security/Cryptography/DvbCsa2.cs new file mode 100644 index 0000000..283a74f --- /dev/null +++ b/skyscraper8/Skyscraper/Security/Cryptography/DvbCsa2.cs @@ -0,0 +1,606 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Security.Cryptography +{ + /// + /// Inspired by https://github.com/tsduck/tsduck/blob/master/src/libtsduck/crypto/tsDVBCSA2.cpp + /// + internal class DvbCsa2 + { + public const int KEY_BITS = 64; //!< DVB CSA-2 control words size in bits. + public const int KEY_SIZE = KEY_BITS / 8; //!< DVB CSA-2 control words size in bytes. + public const int BLOCK_SIZE = 8; + + public enum EntropyMode + { + FULL_CW, //!< Keep the full 64-bit control word. + REDUCE_ENTROPY //!< Reduce the entropy of the control word to 48 bits. + }; + + public DvbCsa2(EntropyMode mode = EntropyMode.REDUCE_ENTROPY) + { + SetEntropyMode(mode); + canProcessInPlace(true); + } + + static readonly int[] sbox1 = { + 2,0,1,1,2,3,3,0, + 3,2,2,0,1,1,0,3, + 0,3,3,0,2,2,1,1, + 2,2,0,3,1,1,3,0 + }; + + static readonly int[] sbox2 = { + 3,1,0,2,2,3,3,0, + 1,3,2,1,0,0,1,2, + 3,1,0,3,3,2,0,2, + 0,0,1,2,2,1,3,1 + }; + + static readonly int[] sbox3 = { + 2,0,1,2,2,3,3,1, + 1,1,0,3,3,0,2,0, + 1,3,0,1,3,0,2,2, + 2,0,1,2,0,3,3,1 + }; + + static readonly int[] sbox4 = { + 3,1,2,3,0,2,1,2, + 1,2,0,1,3,0,0,3, + 1,0,3,1,2,3,0,3, + 0,3,2,0,1,2,2,1 + }; + + static readonly int[] sbox5 = { + 2,0,0,1,3,2,3,2, + 0,1,3,3,1,0,2,1, + 2,3,2,0,0,3,1,1, + 1,0,3,2,3,1,0,2 + }; + + static readonly int[] sbox6 = { + 0,1,2,3,1,2,2,0, + 0,1,3,0,2,3,1,3, + 2,3,0,2,3,0,1,1, + 2,1,1,2,0,3,3,0 + }; + + static readonly int[] sbox7 = { + 0,3,2,2,3,0,0,1, + 3,0,1,3,1,2,2,1, + 1,0,3,3,0,1,1,2, + 2,3,1,0,2,3,0,2 + }; + + + private void canProcessInPlace(bool b) + { + throw new NotImplementedException(); + } + + public void SetEntropyMode(EntropyMode mode) + { + _mode = mode; + } + + public EntropyMode GetEntropyMode() + { + return _mode; + } + + public static void ReduceCW(Span cw) + { + cw[3] = (byte)(cw[0] + cw[1] + cw[2]); + cw[7] = (byte)(cw[4] + cw[5] + cw[6]); + } + + public static bool IsReducedCW(Span cw) + { + return cw[3] == (byte)(cw[0] + cw[1] + cw[2]) && cw[7] == (byte)(cw[4] + cw[5] + cw[6]); + } + + protected static object Properties() + { + return new Tuple("DVB-CSA2", BLOCK_SIZE, KEY_SIZE); + } + + protected bool SetKeyImpl(byte[] newKey) + { + // Only one possible key size. + if (newKey.Length != KEY_SIZE) + { + return false; + } + + // Preprocess control word + _key = new byte[newKey.Length]; + Array.Copy(newKey, 0, _key, 0, newKey.Length); + if (_mode == EntropyMode.REDUCE_ENTROPY) + { + ReduceCW(_key); + } + + // Block cipher key schedule + if (_block == null) + _block = new DvbBlockCipher(); + _block.Init(_key); + + // Stream cipher initialization + if (_stream == null) + _stream = new DvbStreamCipher(); + _stream.Init(_key); + + // Mark as initialized + _init = true; + return true; + } + + protected static bool EncryptImpl(Span plain, int plain_length, Span cipher, int cipher_maxsize, ref int cipher_length) + { + throw new NotImplementedException(); + } + + protected bool DecryptImpl(Span cipher, int cipher_length, Span plain, int plain_maxsize, ref int plain_length) + { + throw new NotImplementedException(); + } + + private class DvbBlockCipher + { + private readonly byte[] key_perm = { + 0x12, 0x24, 0x09, 0x07, 0x2A, 0x31, 0x1D, 0x15, + 0x1C, 0x36, 0x3E, 0x32, 0x13, 0x21, 0x3B, 0x40, + 0x18, 0x14, 0x25, 0x27, 0x02, 0x35, 0x1B, 0x01, + 0x22, 0x04, 0x0D, 0x0E, 0x39, 0x28, 0x1A, 0x29, + 0x33, 0x23, 0x34, 0x0C, 0x16, 0x30, 0x1E, 0x3A, + 0x2D, 0x1F, 0x08, 0x19, 0x17, 0x2F, 0x3D, 0x11, + 0x3C, 0x05, 0x38, 0x2B, 0x0B, 0x06, 0x0A, 0x2C, + 0x20, 0x3F, 0x2E, 0x0F, 0x03, 0x26, 0x10, 0x37 + }; + + // S-Box + + private readonly byte[] block_sbox = { + 0x3A, 0xEA, 0x68, 0xFE, 0x33, 0xE9, 0x88, 0x1A, + 0x83, 0xCF, 0xE1, 0x7F, 0xBA, 0xE2, 0x38, 0x12, + 0xE8, 0x27, 0x61, 0x95, 0x0C, 0x36, 0xE5, 0x70, + 0xA2, 0x06, 0x82, 0x7C, 0x17, 0xA3, 0x26, 0x49, + 0xBE, 0x7A, 0x6D, 0x47, 0xC1, 0x51, 0x8F, 0xF3, + 0xCC, 0x5B, 0x67, 0xBD, 0xCD, 0x18, 0x08, 0xC9, + 0xFF, 0x69, 0xEF, 0x03, 0x4E, 0x48, 0x4A, 0x84, + 0x3F, 0xB4, 0x10, 0x04, 0xDC, 0xF5, 0x5C, 0xC6, + 0x16, 0xAB, 0xAC, 0x4C, 0xF1, 0x6A, 0x2F, 0x3C, + 0x3B, 0xD4, 0xD5, 0x94, 0xD0, 0xC4, 0x63, 0x62, + 0x71, 0xA1, 0xF9, 0x4F, 0x2E, 0xAA, 0xC5, 0x56, + 0xE3, 0x39, 0x93, 0xCE, 0x65, 0x64, 0xE4, 0x58, + 0x6C, 0x19, 0x42, 0x79, 0xDD, 0xEE, 0x96, 0xF6, + 0x8A, 0xEC, 0x1E, 0x85, 0x53, 0x45, 0xDE, 0xBB, + 0x7E, 0x0A, 0x9A, 0x13, 0x2A, 0x9D, 0xC2, 0x5E, + 0x5A, 0x1F, 0x32, 0x35, 0x9C, 0xA8, 0x73, 0x30, + + 0x29, 0x3D, 0xE7, 0x92, 0x87, 0x1B, 0x2B, 0x4B, + 0xA5, 0x57, 0x97, 0x40, 0x15, 0xE6, 0xBC, 0x0E, + 0xEB, 0xC3, 0x34, 0x2D, 0xB8, 0x44, 0x25, 0xA4, + 0x1C, 0xC7, 0x23, 0xED, 0x90, 0x6E, 0x50, 0x00, + 0x99, 0x9E, 0x4D, 0xD9, 0xDA, 0x8D, 0x6F, 0x5F, + 0x3E, 0xD7, 0x21, 0x74, 0x86, 0xDF, 0x6B, 0x05, + 0x8E, 0x5D, 0x37, 0x11, 0xD2, 0x28, 0x75, 0xD6, + 0xA7, 0x77, 0x24, 0xBF, 0xF0, 0xB0, 0x02, 0xB7, + 0xF8, 0xFC, 0x81, 0x09, 0xB1, 0x01, 0x76, 0x91, + 0x7D, 0x0F, 0xC8, 0xA0, 0xF2, 0xCB, 0x78, 0x60, + 0xD1, 0xF7, 0xE0, 0xB5, 0x98, 0x22, 0xB3, 0x20, + 0x1D, 0xA6, 0xDB, 0x7B, 0x59, 0x9F, 0xAE, 0x31, + 0xFB, 0xD3, 0xB6, 0xCA, 0x43, 0x72, 0x07, 0xF4, + 0xD8, 0x41, 0x14, 0x55, 0x0D, 0x54, 0x8B, 0xB9, + 0xAD, 0x46, 0x0B, 0xAF, 0x80, 0x52, 0x2C, 0xFA, + 0x8C, 0x89, 0x66, 0xFD, 0xB2, 0xA9, 0x9B, 0xC0 + }; + + // Permutations + + private readonly byte[] block_perm = { + 0x00, 0x02, 0x80, 0x82, 0x20, 0x22, 0xA0, 0xA2, + 0x10, 0x12, 0x90, 0x92, 0x30, 0x32, 0xB0, 0xB2, + 0x04, 0x06, 0x84, 0x86, 0x24, 0x26, 0xA4, 0xA6, + 0x14, 0x16, 0x94, 0x96, 0x34, 0x36, 0xB4, 0xB6, + 0x40, 0x42, 0xC0, 0xC2, 0x60, 0x62, 0xE0, 0xE2, + 0x50, 0x52, 0xD0, 0xD2, 0x70, 0x72, 0xF0, 0xF2, + 0x44, 0x46, 0xC4, 0xC6, 0x64, 0x66, 0xE4, 0xE6, + 0x54, 0x56, 0xD4, 0xD6, 0x74, 0x76, 0xF4, 0xF6, + 0x01, 0x03, 0x81, 0x83, 0x21, 0x23, 0xA1, 0xA3, + 0x11, 0x13, 0x91, 0x93, 0x31, 0x33, 0xB1, 0xB3, + 0x05, 0x07, 0x85, 0x87, 0x25, 0x27, 0xA5, 0xA7, + 0x15, 0x17, 0x95, 0x97, 0x35, 0x37, 0xB5, 0xB7, + 0x41, 0x43, 0xC1, 0xC3, 0x61, 0x63, 0xE1, 0xE3, + 0x51, 0x53, 0xD1, 0xD3, 0x71, 0x73, 0xF1, 0xF3, + 0x45, 0x47, 0xC5, 0xC7, 0x65, 0x67, 0xE5, 0xE7, + 0x55, 0x57, 0xD5, 0xD7, 0x75, 0x77, 0xF5, 0xF7, + + 0x08, 0x0A, 0x88, 0x8A, 0x28, 0x2A, 0xA8, 0xAA, + 0x18, 0x1A, 0x98, 0x9A, 0x38, 0x3A, 0xB8, 0xBA, + 0x0C, 0x0E, 0x8C, 0x8E, 0x2C, 0x2E, 0xAC, 0xAE, + 0x1C, 0x1E, 0x9C, 0x9E, 0x3C, 0x3E, 0xBC, 0xBE, + 0x48, 0x4A, 0xC8, 0xCA, 0x68, 0x6A, 0xE8, 0xEA, + 0x58, 0x5A, 0xD8, 0xDA, 0x78, 0x7A, 0xF8, 0xFA, + 0x4C, 0x4E, 0xCC, 0xCE, 0x6C, 0x6E, 0xEC, 0xEE, + 0x5C, 0x5E, 0xDC, 0xDE, 0x7C, 0x7E, 0xFC, 0xFE, + 0x09, 0x0B, 0x89, 0x8B, 0x29, 0x2B, 0xA9, 0xAB, + 0x19, 0x1B, 0x99, 0x9B, 0x39, 0x3B, 0xB9, 0xBB, + 0x0D, 0x0F, 0x8D, 0x8F, 0x2D, 0x2F, 0xAD, 0xAF, + 0x1D, 0x1F, 0x9D, 0x9F, 0x3D, 0x3F, 0xBD, 0xBF, + 0x49, 0x4B, 0xC9, 0xCB, 0x69, 0x6B, 0xE9, 0xEB, + 0x59, 0x5B, 0xD9, 0xDB, 0x79, 0x7B, 0xF9, 0xFB, + 0x4D, 0x4F, 0xCD, 0xCF, 0x6D, 0x6F, 0xED, 0xEF, + 0x5D, 0x5F, 0xDD, 0xDF, 0x7D, 0x7F, 0xFD, 0xFF + }; + + + private int[] _kk; //57 items + public void Init(Span key) + { + int i, j, k; + int[] bit = new int[64]; + int[] newbit = new int[64]; + int[][] kb = new int[8][]; // original code was: int kb[9][8]; + for (int init = 0; init < kb.Length; init++) + { + kb[init] = new int[9]; + } + + // 56 steps + // 56 key bytes kk(56)..kk(1) by key schedule from key + + // kb(7,1) .. kb(7,8) = key(1) .. key(8) + kb[7][1] = key[0]; + kb[7][2] = key[1]; + kb[7][3] = key[2]; + kb[7][4] = key[3]; + kb[7][5] = key[4]; + kb[7][6] = key[5]; + kb[7][7] = key[6]; + kb[7][8] = key[7]; + + // calculate kb[6] .. kb[1] + for (i = 0; i < 7; i++) + { + // 64 bit perm on kb + for (j = 0; j < 8; j++) + { + for (k = 0; k < 8; k++) + { + bit[j * 8 + k] = (kb[7 - i][1 + j] >> (7 - k)) & 1; + newbit[key_perm[j * 8 + k] - 1] = bit[j * 8 + k]; + } + } + for (j = 0; j < 8; j++) + { + kb[6 - i][1 + j] = 0; + for (k = 0; k < 8; k++) + { + kb[6 - i][1 + j] |= newbit[j * 8 + k] << (7 - k); + } + } + } + + // xor to give kk + for (i = 0; i < 7; i++) + { + for (j = 0; j < 8; j++) + { + _kk[1 + i * 8 + j] = kb[1 + i][1 + j] ^ i; + } + } + } + public void Encipher(Span bd, Span ib) + { + int i; + int sbox_in; + int sbox_out; + int perm_out; + int[] R = new int[9]; + int next_R1; + + R[1] = bd[0]; + R[2] = bd[1]; + R[3] = bd[2]; + R[4] = bd[3]; + R[5] = bd[4]; + R[6] = bd[5]; + R[7] = bd[6]; + R[8] = bd[7]; + + // loop over kk[1]..kk[56] + for (i = 1; i <= 56; i++) + { + sbox_in = _kk[i] ^ R[8]; + sbox_out = block_sbox[sbox_in]; + perm_out = block_perm[sbox_out]; + next_R1 = R[2]; + R[2] = R[3] ^ R[1]; + R[3] = R[4] ^ R[1]; + R[4] = R[5] ^ R[1]; + R[5] = R[6]; + R[6] = R[7] ^ perm_out; + R[7] = R[8]; + R[8] = R[1] ^ sbox_out; + R[1] = next_R1; + } + + ib[0] = (byte)(R[1]); + ib[1] = (byte)(R[2]); + ib[2] = (byte)(R[3]); + ib[3] = (byte)(R[4]); + ib[4] = (byte)(R[5]); + ib[5] = (byte)(R[6]); + ib[6] = (byte)(R[7]); + ib[7] = (byte)(R[8]); + } + public void Decipher(Span ib, Span bd) + { + int i; + int sbox_in; + int sbox_out; + int perm_out; + int[] R = new int[9]; + int next_R8; + + R[1] = ib[0]; + R[2] = ib[1]; + R[3] = ib[2]; + R[4] = ib[3]; + R[5] = ib[4]; + R[6] = ib[5]; + R[7] = ib[6]; + R[8] = ib[7]; + + // loop over kk[56]..kk[1] + for (i = 56; i > 0; i--) + { + sbox_in = _kk[i] ^ R[7]; + sbox_out = block_sbox[sbox_in]; + perm_out = block_perm[sbox_out]; + next_R8 = R[7]; + R[7] = R[6] ^ perm_out; + R[6] = R[5]; + R[5] = R[4] ^ R[8] ^ sbox_out; + R[4] = R[3] ^ R[8] ^ sbox_out; + R[3] = R[2] ^ R[8] ^ sbox_out; + R[2] = R[1]; + R[1] = R[8] ^ sbox_out; + R[8] = next_R8; + } + + bd[0] = (byte)(R[1]); + bd[1] = (byte)(R[2]); + bd[2] = (byte)(R[3]); + bd[3] = (byte)(R[4]); + bd[4] = (byte)(R[5]); + bd[5] = (byte)(R[6]); + bd[6] = (byte)(R[7]); + bd[7] = (byte)(R[8]); + } + } + + private class DvbStreamCipher + { + private int[] A; //11 bytes + private int[] B; //11 bytes + private int X; + private int Y; + private int Z; + private int D; + private int E; + private int F; + private int p; + private int q; + private int r; + + public void Init(Span key) + { + A[1] = (key[0] >> 4) & 0x0F; + A[2] = (key[0] >> 0) & 0x0F; + A[3] = (key[1] >> 4) & 0x0F; + A[4] = (key[1] >> 0) & 0x0F; + A[5] = (key[2] >> 4) & 0x0F; + A[6] = (key[2] >> 0) & 0x0F; + A[7] = (key[3] >> 4) & 0x0F; + A[8] = (key[3] >> 0) & 0x0F; + A[9] = 0; + A[10] = 0; + + B[1] = (key[4] >> 4) & 0x0F; + B[2] = (key[4] >> 0) & 0x0F; + B[3] = (key[5] >> 4) & 0x0F; + B[4] = (key[5] >> 0) & 0x0F; + B[5] = (key[6] >> 4) & 0x0F; + B[6] = (key[6] >> 0) & 0x0F; + B[7] = (key[7] >> 4) & 0x0F; + B[8] = (key[7] >> 0) & 0x0F; + B[9] = 0; + B[10] = 0; + + X = 0; + Y = 0; + Z = 0; + D = 0; + E = 0; + F = 0; + p = 0; + q = 0; + r = 0; + } + + public void Cipher(Span sb, Span cb) + { + bool init = sb != null; + int i, j; + int in1 = 0; // most significant nibble of input byte + int in2 = 0; // least significant nibble of input byte + int op; + int extra_B; + int s1, s2, s3, s4, s5, s6, s7; + int next_A1; + int next_B1; + int next_E; + + // 8 bytes per operation + for (i = 0; i < 8; i++) + { + if (init) + { + in1 = (sb[i] >> 4) & 0x0F; + in2 = sb[i] & 0x0F; + } + op = 0; + // 2 bits per iteration + for (j = 0; j < 4; j++) + { + // from A[1]..A[10], 35 bits are selected as inputs to 7 s-boxes + // 5 bits input per s-box, 2 bits output per s-box + s1 = sbox1[(((A[4] >> 0) & 1) << 4) | + (((A[1] >> 2) & 1) << 3) | + (((A[6] >> 1) & 1) << 2) | + (((A[7] >> 3) & 1) << 1) | + (((A[9] >> 0) & 1) << 0)]; + s2 = sbox2[(((A[2] >> 1) & 1) << 4) | + (((A[3] >> 2) & 1) << 3) | + (((A[6] >> 3) & 1) << 2) | + (((A[7] >> 0) & 1) << 1) | + (((A[9] >> 1) & 1) << 0)]; + s3 = sbox3[(((A[1] >> 3) & 1) << 4) | + (((A[2] >> 0) & 1) << 3) | + (((A[5] >> 1) & 1) << 2) | + (((A[5] >> 3) & 1) << 1) | + (((A[6] >> 2) & 1) << 0)]; + s4 = sbox4[(((A[3] >> 3) & 1) << 4) | + (((A[1] >> 1) & 1) << 3) | + (((A[2] >> 3) & 1) << 2) | + (((A[4] >> 2) & 1) << 1) | + (((A[8] >> 0) & 1) << 0)]; + s5 = sbox5[(((A[5] >> 2) & 1) << 4) | + (((A[4] >> 3) & 1) << 3) | + (((A[6] >> 0) & 1) << 2) | + (((A[8] >> 1) & 1) << 1) | + (((A[9] >> 2) & 1) << 0)]; + s6 = sbox6[(((A[3] >> 1) & 1) << 4) | + (((A[4] >> 1) & 1) << 3) | + (((A[5] >> 0) & 1) << 2) | + (((A[7] >> 2) & 1) << 1) | + (((A[9] >> 3) & 1) << 0)]; + s7 = sbox7[(((A[2] >> 2) & 1) << 4) | + (((A[3] >> 0) & 1) << 3) | + (((A[7] >> 1) & 1) << 2) | + (((A[8] >> 2) & 1) << 1) | + (((A[8] >> 3) & 1) << 0)]; + + // use 4x4 xor to produce extra nibble for T3 + extra_B = + (((B[3] & 1) << 3) ^ + ((B[6] & 2) << 2) ^ + ((B[7] & 4) << 1) ^ + ((B[9] & 8) >> 0)) | + (((B[6] & 1) << 2) ^ + ((B[8] & 2) << 1) ^ + ((B[3] & 8) >> 1) ^ + ((B[4] & 4) >> 0)) | + (((B[5] & 8) >> 2) ^ + ((B[8] & 4) >> 1) ^ + ((B[4] & 1) << 1) ^ + ((B[5] & 2) >> 0)) | + (((B[9] & 4) >> 2) ^ + ((B[6] & 8) >> 3) ^ + ((B[3] & 2) >> 1) ^ + ((B[8] & 1) >> 0)); + + // T1 = xor all inputs + // in1, in2, D are only used in T1 during initialisation, + // not generation + next_A1 = A[10] ^ X; + if (init) + { + next_A1 = next_A1 ^ D ^ ((j % 2) != 0 ? in2 : in1); + } + + // T2 = xor all inputs + // in1,in2 are only used in T1 during initialisation, not generation + // if p=0, use this, if p=1, rotate the result left + next_B1 = B[7] ^ B[10] ^ Y; + if (init) + { + next_B1 = next_B1 ^ ((j % 2) != 0 ? in1 : in2); + } + + // if p=1, rotate left + if (p != 0) + { + next_B1 = ((next_B1 << 1) | ((next_B1 >> 3) & 1)) & 0x0F; + } + + // T3 = xor all inputs + D = E ^ Z ^ extra_B; + + // T4 = sum, carry of Z + E + r + next_E = F; + if (q != 0) + { + F = Z + E + r; + // r is the carry + r = (F >> 4) & 1; + F = F & 0x0F; + } + else + { + F = E; + } + E = next_E; + + A[10] = A[9]; + A[9] = A[8]; + A[8] = A[7]; + A[7] = A[6]; + A[6] = A[5]; + A[5] = A[4]; + A[4] = A[3]; + A[3] = A[2]; + A[2] = A[1]; + A[1] = next_A1; + + B[10] = B[9]; + B[9] = B[8]; + B[8] = B[7]; + B[7] = B[6]; + B[6] = B[5]; + B[5] = B[4]; + B[4] = B[3]; + B[3] = B[2]; + B[2] = B[1]; + B[1] = next_B1; + + X = ((s4 & 1) << 3) | ((s3 & 1) << 2) | (s2 & 2) | ((s1 & 2) >> 1); + Y = ((s6 & 1) << 3) | ((s5 & 1) << 2) | (s4 & 2) | ((s3 & 2) >> 1); + Z = ((s2 & 1) << 3) | ((s1 & 1) << 2) | (s6 & 2) | ((s5 & 2) >> 1); + p = (s7 & 2) >> 1; + q = (s7 & 1); + + // require 4 loops per output byte + // 2 output bits are a function of the 4 bits of D + // xor 2 by 2 + op = (op << 2) ^ ((((D ^ (D >> 1)) >> 1) & 2) | ((D ^ (D >> 1)) & 1)); + } + // return input data during init + cb[i] = init ? sb[i] : (byte)(op); + } + } + } + + private bool _init = false; + private EntropyMode _mode = EntropyMode.REDUCE_ENTROPY; + private byte[] _key; //KEY_SIZE elements; + private DvbBlockCipher _block; + private DvbStreamCipher _stream; + } +} diff --git a/skyscraper8/VersionInfo.cs b/skyscraper8/VersionInfo.cs index 5977d87..35e2afd 100644 --- a/skyscraper8/VersionInfo.cs +++ b/skyscraper8/VersionInfo.cs @@ -4,7 +4,7 @@ namespace skyscraper8; public class VersionInfo { - private const int PUBLIC_RELEASE = 15; + private const int PUBLIC_RELEASE = 16; public static int GetPublicReleaseNumber() { @@ -15,7 +15,8 @@ public class VersionInfo { try { - Assembly executingAssembly = typeof(VersionInfo).GetTypeInfo().Assembly; + + Assembly executingAssembly = typeof(VersionInfo).GetTypeInfo().Assembly; AssemblyName assemblyName = executingAssembly.GetName(); Version version = assemblyName.Version; DateTime buildDate = new DateTime(2000, 1, 1)