Example #1
0
        private void testReset()
        {
            CipherKeyGenerator gen = new Poly1305KeyGenerator();

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

            byte[] m      = new byte[10000];
            byte[] check  = new byte[16];
            byte[] output = new byte[16];

            // Generate baseline
            IMac poly = new Poly1305(new AesFastEngine());

            poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16]));

            poly.BlockUpdate(m, 0, m.Length);
            poly.DoFinal(check, 0);

            // Check reset after doFinal
            poly.BlockUpdate(m, 0, m.Length);
            poly.DoFinal(output, 0);

            if (!Arrays.AreEqual(check, output))
            {
                Fail("Mac not reset after doFinal");
            }

            // Check reset
            poly.Update((byte)1);
            poly.Update((byte)2);
            poly.Reset();
            poly.BlockUpdate(m, 0, m.Length);
            poly.DoFinal(output, 0);

            if (!Arrays.AreEqual(check, output))
            {
                Fail("Mac not reset after doFinal");
            }

            // Check init resets
            poly.Update((byte)1);
            poly.Update((byte)2);
            poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16]));
            poly.BlockUpdate(m, 0, m.Length);
            poly.DoFinal(output, 0);

            if (!Arrays.AreEqual(check, output))
            {
                Fail("Mac not reset after doFinal");
            }
        }
Example #2
0
        public void PolyReferenceTests(byte[] key, byte[] iv, byte[] data, byte[] expected)
        {
            Poly pmac = new Poly(Common.AesFactory);

            pmac.Init(key, iv, 16);
            pmac.Process(new ArraySegment <byte>(data));
            byte[] mac = pmac.Compute();

            var bcpoly = new Poly1305(new AesEngine());

            bcpoly.Init(new ParametersWithIV(new KeyParameter(key), iv));
            bcpoly.BlockUpdate(data, 0, data.Length);
            byte[] bcmac = new byte[bcpoly.GetMacSize()];
            bcpoly.DoFinal(bcmac, 0);

            var _key      = string.Join(", ", key.Select(b => $"0x{b:x2}"));
            var _iv       = string.Join(", ", iv.Select(b => $"0x{b:x2}"));
            var _data     = string.Join(", ", data.Select(b => $"0x{b:x2}"));
            var _expected = string.Join(", ", bcmac.Select(b => $"0x{b:x2}"));

            Log.Verbose($"[InlineData(new byte[] {{{_key}}}, new byte[] {{{_iv}}}, new byte[] {{{_data}}}, new byte[] {{{_expected}}})]");

            Assert.Equal(expected, mac);
            Assert.Equal(expected, bcmac);
        }
Example #3
0
        private void testCase(int i)
        {
            byte[]   output = new byte[16];
            TestCase tc     = CASES[i];

            IMac mac;

            if (tc.nonce == null)
            {
                // Raw Poly1305 test - don't do any transform on AES key part
                mac = new Poly1305(new KeyEngine(16));
                mac.Init(new ParametersWithIV(new KeyParameter(tc.key), new byte[16]));
            }
            else
            {
                mac = new Poly1305(new AesFastEngine());
                mac.Init(new ParametersWithIV(new KeyParameter(tc.key), tc.nonce));
            }
            mac.BlockUpdate(tc.message, 0, tc.message.Length);
            mac.DoFinal(output, 0);

            if (!Arrays.AreEqual(output, tc.expectedMac))
            {
                Fail("Mismatched output " + i, Hex.ToHexString(tc.expectedMac), Hex.ToHexString(output));
            }
        }
Example #4
0
        private void testInit()
        {
            CipherKeyGenerator gen = new Poly1305KeyGenerator();

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

            IMac poly = new Poly1305(new AesFastEngine());

            poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16]));

            try
            {
                poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[15]));
                Fail("16 byte nonce required");
            }
            catch (ArgumentException)
            {
                // Expected
            }

            try
            {
                byte[] k2 = new byte[k.Length - 1];
                Array.Copy(k, 0, k2, 0, k2.Length);
                poly.Init(new ParametersWithIV(new KeyParameter(k2), new byte[16]));
                Fail("32 byte key required");
            }
            catch (ArgumentException)
            {
                // Expected
            }

            /*
             *          try
             *          {
             *                  k[19] = (byte)0xFF;
             *                  poly.Init(new ParametersWithIV(new KeyParameter(k), new byte[16]));
             *                  Fail("UnClamped key should not be accepted.");
             *          }
             * catch (ArgumentException)
             *          {
             *                  // Expected
             *          }
             */
        }
Example #5
0
        static bool crypto_aead_chacha20poly1305_ietf_decrypt_detached(Memory <byte> m, ReadOnlyMemory <byte> c, ReadOnlyMemory <byte> mac, ReadOnlyMemory <byte> ad, ReadOnlyMemory <byte> npub, ReadOnlyMemory <byte> k)
        {
            var kk = k._AsSegment();
            var nn = npub._AsSegment();
            var cc = c._AsSegment();
            var aa = ad._AsSegment();
            var mm = m._AsSegment();

            byte[] block0 = new byte[64];

            ChaCha7539Engine ctx = new ChaCha7539Engine();

            ctx.Init(true, new ParametersWithIV(new KeyParameter(kk.Array, kk.Offset, kk.Count), nn.Array, nn.Offset, nn.Count));
            ctx.ProcessBytes(block0, 0, block0.Length, block0, 0);

            Poly1305 state = new Poly1305();

            state.Init(new KeyParameter(block0, 0, AeadChaCha20Poly1305KeySize));

            state.BlockUpdate(aa.Array, aa.Offset, aa.Count);
            if ((aa.Count % 16) != 0)
            {
                state.BlockUpdate(zero15, 0, 16 - (aa.Count % 16));
            }

            state.BlockUpdate(cc.Array, cc.Offset, cc.Count);
            if ((cc.Count % 16) != 0)
            {
                state.BlockUpdate(zero15, 0, 16 - (cc.Count % 16));
            }

            byte[] slen = BitConverter.GetBytes((ulong)aa.Count);
            if (Env.IsBigEndian)
            {
                Array.Reverse(slen);
            }
            state.BlockUpdate(slen, 0, slen.Length);

            byte[] mlen = BitConverter.GetBytes((ulong)cc.Count);
            if (Env.IsBigEndian)
            {
                Array.Reverse(mlen);
            }
            state.BlockUpdate(mlen, 0, mlen.Length);

            byte[] computed_mac = new byte[AeadChaCha20Poly1305MacSize];
            state.DoFinal(computed_mac, 0);

            if (computed_mac.AsSpan().SequenceEqual(mac.Span) == false)
            {
                return(false);
            }

            ctx.ProcessBytes(cc.Array, cc.Offset, cc.Count, mm.Array, mm.Offset);

            return(true);
        }
Example #6
0
        protected virtual byte[] CalculateRecordMac(KeyParameter macKey, byte[] additionalData, byte[] buf, int off, int len)
        {
            IMac mac = new Poly1305();

            mac.Init(macKey);
            this.UpdateRecordMac(mac, additionalData, 0, additionalData.Length);
            this.UpdateRecordMac(mac, buf, off, len);
            return(MacUtilities.DoFinal(mac));
        }
Example #7
0
        /// <summary>
        /// Branca specification-level token generation
        /// </summary>
        /// <param name="payload">The payload to be encrypted into the Branca token</param>
        /// <param name="key">32-byte private key used to encrypt and decrypt the Branca token</param>
        /// <returns>Base62 encoded Branca Token</returns>
        public virtual string CreateToken(string payload, byte[] key)
        {
            if (string.IsNullOrWhiteSpace(payload))
            {
                throw new ArgumentNullException(nameof(payload));
            }
            if (!IsValidKey(key))
            {
                throw new InvalidOperationException("Invalid encryption key");
            }

            var nonce = new byte[24];

            RandomNumberGenerator.Create().GetBytes(nonce);

            var timestamp = Convert.ToUInt32(DateTimeOffset.UtcNow.ToUnixTimeSeconds());

            // header
            var header = new byte[29];

            using (var stream = new MemoryStream(header))
            {
                // version
                stream.WriteByte(0xBA);

                // timestamp
                stream.Write(BitConverter.GetBytes(timestamp), 0, 4);

                // nonce
                stream.Write(nonce, 0, nonce.Length);
            }

            var keyMaterial = new KeyParameter(key);
            var parameters  = new ParametersWithIV(keyMaterial, nonce);

            var engine = new XChaChaEngine();

            engine.Init(true, parameters);

            var plaintextBytes = Encoding.UTF8.GetBytes(payload);
            var ciphertext     = new byte[plaintextBytes.Length + 16];

            engine.ProcessBytes(plaintextBytes, 0, plaintextBytes.Length, ciphertext, 0);

            var poly = new Poly1305();

            poly.Init(keyMaterial);
            poly.BlockUpdate(header, 0, header.Length);
            poly.DoFinal(ciphertext, plaintextBytes.Length);

            var tokenBytes = new byte[header.Length + ciphertext.Length];

            Buffer.BlockCopy(header, 0, tokenBytes, 0, header.Length);
            Buffer.BlockCopy(ciphertext, 0, tokenBytes, header.Length, ciphertext.Length);

            return(Base62.Encode(tokenBytes));
        }
Example #8
0
        public virtual void Init(
            bool forEncryption,
            ICipherParameters parameters)
        {
            this.forEncryption = forEncryption;

            KeyParameter keyParam;

            if (parameters is AeadParameters)
            {
                AeadParameters param = (AeadParameters)parameters;

                nonce = param.GetNonce();
                initialAssociatedText = param.GetAssociatedText();

                keyParam = param.Key;
            }
            else if (parameters is ParametersWithIV)
            {
                ParametersWithIV param = (ParametersWithIV)parameters;

                nonce = param.GetIV();
                initialAssociatedText = null;
                keyParam = (KeyParameter)param.Parameters;
            }
            else
            {
                throw new ArgumentException("invalid parameters passed to ChaCha20Poly1305");
            }

            if (nonce == null || nonce.Length < 1)
            {
                throw new ArgumentException("IV must be at least 1 byte");
            }

            //  Geneate the key
            ChaChaX tmpCypher = new ChaChaX();

            byte[]           zero    = new byte[32];
            byte[]           polyKey = new byte[32];
            ParametersWithIV tmpKey  = new ParametersWithIV(keyParam, nonce);

            tmpCypher.Init(true, tmpKey);
            tmpCypher.ProcessBytes(zero, 0, zero.Length, polyKey, 0);

            poly = new Poly1305();

            KeyParameter tmpKey2 = new KeyParameter(polyKey);

            poly.Init(tmpKey2);

            chacha20 = new ChaChaX();
            chacha20.Init(forEncryption, tmpKey);

            InitCipher();
        }
Example #9
0
        private static byte[] CalculateMac(byte[] key, byte[] data)
        {
            var      tag  = new byte[16];
            Poly1305 poly = new Poly1305();

            poly.Init(new KeyParameter(key));
            poly.BlockUpdate(data, 0, data.Length);
            poly.DoFinal(tag, 0);

            return(tag);
        }
        protected static int CalculateRecordMac(KeyParameter macKey, byte[] additionalData, byte[] buf, int off, int len, byte[] outMac)
        {
            IMac mac = new Poly1305();

            mac.Init(macKey);

            UpdateRecordMacText(mac, additionalData, 0, additionalData.Length);
            UpdateRecordMacText(mac, buf, off, len);
            UpdateRecordMacLength(mac, additionalData.Length);
            UpdateRecordMacLength(mac, len);

            return(MacUtilities.DoFinalOut(mac, outMac));
        }
Example #11
0
        protected /*virtual */ BufferSegment CalculateRecordMac(KeyParameter macKey, BufferSegment additionalData, byte[] buf, int off, int len)
        {
            Poly1305 mac = new Poly1305();

            mac.Init(macKey);

            UpdateRecordMacText(mac, additionalData);
            UpdateRecordMacText(mac, new BufferSegment(buf, off, len));
            UpdateRecordMacLength(mac, additionalData.Count);
            UpdateRecordMacLength(mac, len);

            return(MacUtilities.DoFinalOptimized(mac));
        }
Example #12
0
        private void CheckVector(byte[] keyMaterial, byte[] input, byte[] tag)
        {
            Poly1305 poly1305 = new Poly1305();

            poly1305.Init(new KeyParameter(keyMaterial));

            poly1305.BlockUpdate(input, 0, input.Length);

            byte[] mac = new byte[poly1305.GetMacSize()];

            poly1305.DoFinal(mac, 0);

            if (!Arrays.AreEqual(tag, mac))
            {
                Fail("rfc7539", Hex.ToHexString(tag), Hex.ToHexString(mac));
            }
        }
        private byte[] CalcMac(byte[] key, byte[] nonce, byte[] cipherText, byte[] ad)
        {
            var mac     = new Poly1305();
            var polyKey = EncryptOrDecrypt(true, new byte[32], key, nonce, false);

            mac.Init(new KeyParameter(polyKey));
            mac.BlockUpdate(ad, 0, ad.Length);
            Pad(mac, ad.Length);
            mac.BlockUpdate(cipherText, 0, cipherText.Length);
            Pad(mac, cipherText.Length);
            WriteLE(mac, ad.Length);
            WriteLE(mac, cipherText.Length);
            var tag       = new byte[16];
            var macreslen = mac.DoFinal(tag, 0);

            Debug.Assert(macreslen == 16);
            return(tag);
        }
Example #14
0
        private byte[] EncryptXSalsa20Poly1305(byte[] bytes, byte[] key, byte[] nonce)
        {
            var salsa = new XSalsa20Engine();
            var poly  = new Poly1305();

            salsa.Init(true, new ParametersWithIV(new KeyParameter(key), nonce));

            byte[] subKey = new byte[key.Length];
            salsa.ProcessBytes(subKey, 0, key.Length, subKey, 0);

            byte[] output = new byte[bytes.Length + poly.GetMacSize()];

            salsa.ProcessBytes(bytes, 0, bytes.Length, output, poly.GetMacSize());

            poly.Init(new KeyParameter(subKey));
            poly.BlockUpdate(output, poly.GetMacSize(), bytes.Length);
            poly.DoFinal(output, 0);

            return(output);
        }
Example #15
0
        public void BasicPolyTests(int ivBytes, int dataBytes, int macSize)
        {
            RandomNumberGenerator rng = new RandomNumberGenerator();

            byte[] iv   = rng.Generate(ivBytes);
            byte[] key  = rng.Generate(32);
            byte[] data = rng.Generate(dataBytes);

            Poly pmac   = new Poly(Common.AesFactory);
            var  bcpoly = new Poly1305(new AesEngine());

            pmac.Init(key, iv, macSize);
            bcpoly.Init(new ParametersWithIV(new KeyParameter(key), iv));
            pmac.Process(new ArraySegment <byte>(data));
            byte[] mac = pmac.Compute();

            bcpoly.BlockUpdate(data, 0, data.Length);
            byte[] bcmac = new byte[bcpoly.GetMacSize()];
            bcpoly.DoFinal(bcmac, 0);
            bcmac = bcmac.Take(macSize).ToArray();

            Assert.Equal(bcmac, mac);
        }
Example #16
0
        public void PolyReuseKeyTest(int ivBytes, int dataBytes, int macSize)
        {
            RandomNumberGenerator rng = new RandomNumberGenerator();

            byte[] iv    = rng.Generate(ivBytes);
            byte[] key   = rng.Generate(32);
            byte[] data1 = rng.Generate(dataBytes);
            byte[] data2 = rng.Generate(dataBytes);

            var pmac = new Poly(Common.AesFactory);

            pmac.Init(key, iv, macSize);
            pmac.Process(new ArraySegment <byte>(data1));
            byte[] mac1 = pmac.Compute();
            pmac.Init(key, iv, macSize);
            pmac.Process(new ArraySegment <byte>(data2));
            byte[] mac2 = pmac.Compute();

            var bcpoly1 = new Poly1305(new AesEngine());

            bcpoly1.Init(new ParametersWithIV(new KeyParameter(key), iv));
            bcpoly1.BlockUpdate(data1, 0, data1.Length);
            byte[] bcmac1 = new byte[bcpoly1.GetMacSize()];
            bcpoly1.DoFinal(bcmac1, 0);
            bcmac1 = bcmac1.Take(macSize).ToArray();

            var bcpoly2 = new Poly1305(new AesEngine());

            bcpoly2.Init(new ParametersWithIV(new KeyParameter(key), iv));
            bcpoly2.BlockUpdate(data2, 0, data2.Length);
            byte[] bcmac2 = new byte[bcpoly2.GetMacSize()];
            bcpoly2.DoFinal(bcmac2, 0);
            bcmac2 = bcmac2.Take(macSize).ToArray();

            Assert.Equal(bcmac1, mac1);
            Assert.Equal(bcmac2, mac2);
        }
Example #17
0
        public static void SelfTest()
        {
            byte[] key = new byte[] {
                0x1c, 0x92, 0x40, 0xa5, 0xeb, 0x55, 0xd3, 0x8a, 0xf3, 0x33, 0x88, 0x86, 0x04, 0xf6, 0xb5, 0xf0,
                0x47, 0x39, 0x17, 0xc1, 0x40, 0x2b, 0x80, 0x09, 0x9d, 0xca, 0x5c, 0xbc, 0x20, 0x70, 0x75, 0xc0
            };

            byte[] nonce = new byte[] {
                0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
            };

            byte[] cipherText = new byte[] {
                0x64, 0xa0, 0x86, 0x15, 0x75, 0x86, 0x1a, 0xf4, 0x60, 0xf0, 0x62, 0xc7, 0x9b, 0xe6, 0x43, 0xbd,
                0x5e, 0x80, 0x5c, 0xfd, 0x34, 0x5c, 0xf3, 0x89, 0xf1, 0x08, 0x67, 0x0a, 0xc7, 0x6c, 0x8c, 0xb2,
                0x4c, 0x6c, 0xfc, 0x18, 0x75, 0x5d, 0x43, 0xee, 0xa0, 0x9e, 0xe9, 0x4e, 0x38, 0x2d, 0x26, 0xb0,
                0xbd, 0xb7, 0xb7, 0x3c, 0x32, 0x1b, 0x01, 0x00, 0xd4, 0xf0, 0x3b, 0x7f, 0x35, 0x58, 0x94, 0xcf,
                0x33, 0x2f, 0x83, 0x0e, 0x71, 0x0b, 0x97, 0xce, 0x98, 0xc8, 0xa8, 0x4a, 0xbd, 0x0b, 0x94, 0x81,
                0x14, 0xad, 0x17, 0x6e, 0x00, 0x8d, 0x33, 0xbd, 0x60, 0xf9, 0x82, 0xb1, 0xff, 0x37, 0xc8, 0x55,
                0x97, 0x97, 0xa0, 0x6e, 0xf4, 0xf0, 0xef, 0x61, 0xc1, 0x86, 0x32, 0x4e, 0x2b, 0x35, 0x06, 0x38,
                0x36, 0x06, 0x90, 0x7b, 0x6a, 0x7c, 0x02, 0xb0, 0xf9, 0xf6, 0x15, 0x7b, 0x53, 0xc8, 0x67, 0xe4,
                0xb9, 0x16, 0x6c, 0x76, 0x7b, 0x80, 0x4d, 0x46, 0xa5, 0x9b, 0x52, 0x16, 0xcd, 0xe7, 0xa4, 0xe9,
                0x90, 0x40, 0xc5, 0xa4, 0x04, 0x33, 0x22, 0x5e, 0xe2, 0x82, 0xa1, 0xb0, 0xa0, 0x6c, 0x52, 0x3e,
                0xaf, 0x45, 0x34, 0xd7, 0xf8, 0x3f, 0xa1, 0x15, 0x5b, 0x00, 0x47, 0x71, 0x8c, 0xbc, 0x54, 0x6a,
                0x0d, 0x07, 0x2b, 0x04, 0xb3, 0x56, 0x4e, 0xea, 0x1b, 0x42, 0x22, 0x73, 0xf5, 0x48, 0x27, 0x1a,
                0x0b, 0xb2, 0x31, 0x60, 0x53, 0xfa, 0x76, 0x99, 0x19, 0x55, 0xeb, 0xd6, 0x31, 0x59, 0x43, 0x4e,
                0xce, 0xbb, 0x4e, 0x46, 0x6d, 0xae, 0x5a, 0x10, 0x73, 0xa6, 0x72, 0x76, 0x27, 0x09, 0x7a, 0x10,
                0x49, 0xe6, 0x17, 0xd9, 0x1d, 0x36, 0x10, 0x94, 0xfa, 0x68, 0xf0, 0xff, 0x77, 0x98, 0x71, 0x30,
                0x30, 0x5b, 0xea, 0xba, 0x2e, 0xda, 0x04, 0xdf, 0x99, 0x7b, 0x71, 0x4d, 0x6c, 0x6f, 0x2c, 0x29,
                0xa6, 0xad, 0x5c, 0xb4, 0x02, 0x2b, 0x02, 0x70, 0x9b,
                0xee, 0xad, 0x9d, 0x67, 0x89, 0x0c, 0xbb, 0x22, 0x39, 0x23, 0x36, 0xfe, 0xa1, 0x85, 0x1f, 0x38
            };

            byte[] aad = new byte[] {
                0xf3, 0x33, 0x88, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x91
            };

            byte[] plainText = new byte[] {
                0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x73, 0x20,
                0x61, 0x72, 0x65, 0x20, 0x64, 0x72, 0x61, 0x66, 0x74, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
                0x6e, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20,
                0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x69, 0x78, 0x20, 0x6d,
                0x6f, 0x6e, 0x74, 0x68, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65,
                0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63,
                0x65, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x64,
                0x20, 0x62, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
                0x6e, 0x74, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e,
                0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x70, 0x72,
                0x69, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65,
                0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x73, 0x20, 0x61, 0x73, 0x20, 0x72,
                0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61,
                0x6c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65,
                0x6d, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x73, 0x20,
                0x2f, 0xe2, 0x80, 0x9c, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x67,
                0x72, 0x65, 0x73, 0x73, 0x2e, 0x2f, 0xe2, 0x80, 0x9d
            };

            Poly1305 p = new Poly1305();

            byte[]       pKey    = new byte[] { 0x85, 0xd6, 0xbe, 0x78, 0x57, 0x55, 0x6d, 0x33, 0x7f, 0x44, 0x52, 0xfe, 0x42, 0xd5, 0x06, 0xa8, 0x01, 0x03, 0x80, 0x8a, 0xfb, 0x0d, 0xb2, 0xfd, 0x4a, 0xbf, 0xf6, 0xaf, 0x41, 0x49, 0xf5, 0x1b };
            KeyParameter paramsX = new KeyParameter(pKey);

            p.Init(paramsX);

            byte[] msg = UTF8Encoding.ASCII.GetBytes("Cryptographic Forum Research Group");
            p.BlockUpdate(msg, 0, msg.Length);
            byte[] output = new byte[30];
            p.DoFinal(output, 0);


            ChaCha20Poly1305 cipher = new ChaCha20Poly1305();

            KeyParameter   ContentKey = new KeyParameter(key);
            AeadParameters parameters = new AeadParameters(ContentKey, 128, nonce, aad);

            cipher.Init(true, parameters);

            byte[] C   = new byte[cipher.GetOutputSize(plainText.Length)];
            int    len = cipher.ProcessBytes(plainText, 0, plainText.Length, C, 0);

            len += cipher.DoFinal(C, len);
        }
Example #18
0
        /// <summary>
        /// Branca specification level token decryption.
        /// </summary>
        /// <param name="token">Base62 encoded Branca token</param>
        /// <param name="key">32-byte private key used to encrypt and decrypt the Branca token</param>
        /// <returns>Pared and decrypted Branca Token</returns>
        public virtual BrancaToken DecryptToken(string token, byte[] key)
        {
            if (string.IsNullOrWhiteSpace(token))
            {
                throw new ArgumentNullException(nameof(token));
            }
            if (!CanReadToken(token))
            {
                throw new InvalidCastException("Unable to read token");
            }
            if (!IsValidKey(key))
            {
                throw new InvalidOperationException("Invalid decryption key");
            }

            var tokenBytes = Base62.Decode(token);

            using (var stream = new MemoryStream(tokenBytes, false))
            {
                // header
                var header = GuaranteedRead(stream, 29);

                byte[] nonce;
                uint   timestamp;
                using (var headerStream = new MemoryStream(header))
                {
                    // version
                    var version = headerStream.ReadByte();
                    if (version != 0xBA)
                    {
                        throw new SecurityTokenException("Unsupported Branca version");
                    }

                    // timestamp
                    var timestampBytes = GuaranteedRead(headerStream, 4);
                    timestamp = BitConverter.ToUInt32(timestampBytes, 0);

                    // nonce
                    nonce = GuaranteedRead(headerStream, 24);
                }

                // ciphertext
                var ciphertextLength = (stream.Length - 16) - stream.Position;
                var ciphertext       = GuaranteedRead(stream, (int)ciphertextLength);

                // tag
                var tag = GuaranteedRead(stream, 16);

                // XChaCha20-Poly1305
                var keyMaterial = new KeyParameter(key);
                var parameters  = new ParametersWithIV(keyMaterial, nonce);

                var headerMac = new byte[16];
                var poly1305  = new Poly1305();
                poly1305.Init(keyMaterial);
                poly1305.BlockUpdate(header, 0, header.Length);
                poly1305.DoFinal(headerMac, 0);

                if (!headerMac.SequenceEqual(tag))
                {
                    throw new SecurityTokenException("Invalid message authentication code");
                }

                var engine = new XChaChaEngine();
                engine.Init(false, parameters);
                var decryptedPlaintext = new byte[ciphertext.Length];
                engine.ProcessBytes(ciphertext, 0, ciphertext.Length, decryptedPlaintext, 0);

                return(new BrancaToken(
                           Encoding.UTF8.GetString(decryptedPlaintext),
                           timestamp));
            }
        }
Example #19
0
        private void testSequential()
        {
            // Sequential test, adapted from test-poly1305aes
            int len;

            byte[] kr     = new byte[32];
            byte[] m      = new byte[MAXLEN];
            byte[] n      = new byte[16];
            byte[] output = new byte[16];

            int  c   = 0;
            IMac mac = new Poly1305(new AesFastEngine());

            for (int loop = 0; loop < 13; loop++)
            {
                len = 0;
                for (;;)
                {
                    c++;
                    mac.Init(new ParametersWithIV(new KeyParameter(kr), n));
                    mac.BlockUpdate(m, 0, len);
                    mac.DoFinal(output, 0);

                    // if (c == 678)
                    // {
                    // TestCase tc = CASES[0];
                    //
                    // if (!Arrays.AreEqual(tc.key, kr))
                    // {
                    // System.err.println("Key bad");
                    // System.err.println(Hex.ToHexString(tc.key)));
                    // System.err.println(Hex.ToHexString(kr)));
                    // System.exit(1);
                    // }
                    // if (!Arrays.AreEqual(tc.nonce, n))
                    // {
                    // System.err.println("Nonce bad");
                    // System.exit(1);
                    // }
                    // System.out.printf("[%d] m: %s\n", c, Hex.ToHexString(m, 0, len)));
                    // System.out.printf("[%d] K: %s\n", c, new string(Hex.encodje(kr)));
                    // System.out.printf("[%d] N: %s\n", c, Hex.ToHexString(n)));
                    // System.out.printf("[%d] M: ", c);
                    // }
                    // System.out.printf("%d/%s\n", c, Hex.ToHexString(out)));

                    if (len >= MAXLEN)
                    {
                        break;
                    }
                    n[0] = (byte)(n[0] ^ loop);
                    for (int i = 0; i < 16; ++i)
                    {
                        n[i] ^= output[i];
                    }
                    if (len % 2 != 0)
                    {
                        for (int i = 0; i < 16; ++i)
                        {
                            kr[i] ^= output[i];
                        }
                    }
                    if (len % 3 != 0)
                    {
                        for (int i = 0; i < 16; ++i)
                        {
                            kr[i + 16] ^= output[i];
                        }
                    }
                    Poly1305KeyGenerator.Clamp(kr);
                    m[len++] ^= output[0];
                }
            }
            // Output after 13 loops as generated by poly1305 ref
            if (c != 13013 || !Arrays.AreEqual(output, Hex.Decode("c96f60a23701a5b0fd2016f58cbe4f7e")))
            {
                Fail("Sequential Poly1305 " + c, "c96f60a23701a5b0fd2016f58cbe4f7e", Hex.ToHexString(output));
            }
        }