Example #1
0
        private void SetKey(byte[] key, byte[] nonce)
        {
            if (cipher != null && (nonce == null || nonce.Length != BLOCK_SIZE))
            {
                throw new ArgumentException("Poly1305 requires a 128 bit IV.");
            }

            Poly1305KeyGenerator.CheckKey(key);

            // Extract r portion of key
            uint t0 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 0);
            uint t1 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 4);
            uint t2 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 8);
            uint t3 = Pack.LE_To_UInt32(key, BLOCK_SIZE + 12);

            r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
            r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
            r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
            r3 = t2 & 0x3f03fff; t3 >>= 8;
            r4 = t3 & 0x00fffff;

            // Precompute multipliers
            s1 = r1 * 5;
            s2 = r2 * 5;
            s3 = r3 * 5;
            s4 = r4 * 5;

            byte[] kBytes;
            if (cipher == null)
            {
                kBytes = key;
            }
            else
            {
                // Compute encrypted nonce
                kBytes = new byte[BLOCK_SIZE];
                cipher.Init(true, new KeyParameter(key, 0, BLOCK_SIZE));
                cipher.ProcessBlock(nonce, 0, kBytes, 0);
            }

            k0 = Pack.LE_To_UInt32(kBytes, 0);
            k1 = Pack.LE_To_UInt32(kBytes, 4);
            k2 = Pack.LE_To_UInt32(kBytes, 8);
            k3 = Pack.LE_To_UInt32(kBytes, 12);
        }
Example #2
0
        private void SetKey(byte[] key, byte[] nonce)
        {
            //IL_0017: Unknown result type (might be due to invalid IL or missing references)
            if (cipher != null && (nonce == null || nonce.Length != 16))
            {
                throw new ArgumentException("Poly1305 requires a 128 bit IV.");
            }
            Poly1305KeyGenerator.CheckKey(key);
            uint num  = Pack.LE_To_UInt32(key, 16);
            uint num2 = Pack.LE_To_UInt32(key, 20);
            uint num3 = Pack.LE_To_UInt32(key, 24);
            uint num4 = Pack.LE_To_UInt32(key, 28);

            r0     = num & 0x3FFFFFFu;
            num  >>= 26;
            num   |= num2 << 6;
            r1     = num & 0x3FFFF03u;
            num2 >>= 20;
            num2  |= num3 << 12;
            r2     = num2 & 0x3FFC0FFu;
            num3 >>= 14;
            num3  |= num4 << 18;
            r3     = num3 & 0x3F03FFFu;
            num4 >>= 8;
            r4     = num4 & 0xFFFFFu;
            s1     = r1 * 5;
            s2     = r2 * 5;
            s3     = r3 * 5;
            s4     = r4 * 5;
            byte[] array;
            if (cipher == null)
            {
                array = key;
            }
            else
            {
                array = new byte[16];
                cipher.Init(forEncryption: true, new KeyParameter(key, 0, 16));
                cipher.ProcessBlock(nonce, 0, array, 0);
            }
            k0 = Pack.LE_To_UInt32(array, 0);
            k1 = Pack.LE_To_UInt32(array, 4);
            k2 = Pack.LE_To_UInt32(array, 8);
            k3 = Pack.LE_To_UInt32(array, 12);
        }
Example #3
0
        private void SetKey(byte[] key, byte[] nonce)
        {
            if (this.cipher != null && (nonce == null || nonce.Length != 16))
            {
                throw new ArgumentException("Poly1305 requires a 128 bit IV.");
            }
            Poly1305KeyGenerator.CheckKey(key);
            uint num  = Pack.LE_To_UInt32(key, 16);
            uint num2 = Pack.LE_To_UInt32(key, 20);
            uint num3 = Pack.LE_To_UInt32(key, 24);
            uint num4 = Pack.LE_To_UInt32(key, 28);

            this.r0 = (num & 67108863u);
            num   >>= 26;
            num    |= num2 << 6;
            this.r1 = (num & 67108611u);
            num2  >>= 20;
            num2   |= num3 << 12;
            this.r2 = (num2 & 67092735u);
            num3  >>= 14;
            num3   |= num4 << 18;
            this.r3 = (num3 & 66076671u);
            num4  >>= 8;
            this.r4 = (num4 & 1048575u);
            this.s1 = this.r1 * 5u;
            this.s2 = this.r2 * 5u;
            this.s3 = this.r3 * 5u;
            this.s4 = this.r4 * 5u;
            byte[] array;
            if (this.cipher == null)
            {
                array = key;
            }
            else
            {
                array = new byte[16];
                this.cipher.Init(true, new KeyParameter(key, 0, 16));
                this.cipher.ProcessBlock(nonce, 0, array, 0);
            }
            this.k0 = Pack.LE_To_UInt32(array, 0);
            this.k1 = Pack.LE_To_UInt32(array, 4);
            this.k2 = Pack.LE_To_UInt32(array, 8);
            this.k3 = Pack.LE_To_UInt32(array, 12);
        }
Example #4
0
        private void testKeyGenerator()
        {
            CipherKeyGenerator gen = new Poly1305KeyGenerator();

            gen.Init(new KeyGenerationParameters(new SecureRandom(), 256));
            byte[] k = gen.GenerateKey();

            if (k.Length != 32)
            {
                Fail("Poly1305 key should be 256 bits.");
            }

            try
            {
                Poly1305KeyGenerator.CheckKey(k);
            }
            catch (ArgumentException)
            {
                Fail("Poly1305 key should be Clamped on generation.");
            }

            byte[] k2 = new byte[k.Length];
            Array.Copy(k, 0, k2, 0, k2.Length);
            Poly1305KeyGenerator.Clamp(k);
            if (!Arrays.AreEqual(k, k2))
            {
                Fail("Poly1305 key should be Clamped on generation.");
            }

            /*
             *          try
             *          {
             *                  k2[19] = (byte)0xff;
             *                  Poly1305KeyGenerator.CheckKey(k2);
             *                  Fail("UnClamped key should fail check.");
             *          }
             * catch (ArgumentException)
             *          {
             *                  // Expected
             *          }
             */
        }
        private KeyParameter InitRecordMAC(ChaChaEngine cipher)
        {
            byte[] zeroes = StringToByteArray(
                "00000000000000000000000000000000"
                + "00000000000000000000000000000000"
                + "00000000000000000000000000000000"
                + "00000000000000000000000000000000");

            byte[] firstBlock = new byte[64];
            cipher.ProcessBytes(zeroes, 0, firstBlock.Length, firstBlock, 0);

            Console.WriteLine("ChaCha OutBytes");
            Console.WriteLine(ByteArrayToString(firstBlock));

            // NOTE: The BC implementation puts 'r' after 'k'
            //Array.Copy(firstBlock, 0, firstBlock, 32, 16);
            //KeyParameter macKey = new KeyParameter(firstBlock, 16, 32);
            //Poly1305KeyGenerator.clamp(macKey.getKey());

            // 8th January, 2018 21:05
            //
            // The above code is from the github HAP-Java implementation. The problem was that the clamp() operator
            // wasn't having any effect! I'm guessing it's because the getKey() returns a new instance each time.
            // To work around this, I create a buffer, clamp it and then create a KeyParameter with the new byte[]
            // How the f**k I spotted this I'll never know.
            //

            KeyParameter macKey = new KeyParameter(firstBlock, 0, 32);

            var key = macKey.GetKey();

            //Console.WriteLine(ByteArrayToString(key));

            Poly1305KeyGenerator.Clamp(key);

            //Console.WriteLine(ByteArrayToString(key));

            Poly1305KeyGenerator.CheckKey(key);

            return(new KeyParameter(key));
        }