示例#1
0
        /// <summary>
        /// Encrypt data with Salsa20
        /// </summary>
        /// <param name="input">Input stream to encrypt</param>
        /// <param name="output">Output stream</param>
        /// <param name="key">Key</param>
        /// <param name="nonce">Nonce</param>
        /// <param name="notifyProgression">Notify progression method</param>
        /// <param name="bufferSize">Buffer size</param>
        public static void Encrypt(Stream input, Stream output, byte[] key, byte[] nonce, Action <int> notifyProgression = null, int bufferSize = 4096)
        {
            Salsa20Engine    engine     = new Salsa20Engine();
            ParametersWithIV parameters = new ParametersWithIV(new KeyParameter(key, 0, key.Length), nonce, 0, nonce.Length);

            engine.Init(true, parameters);

            int bytesRead;

            byte[] buffer = new byte[bufferSize];
            byte[] enc    = new byte[bufferSize];
            do
            {
                bytesRead = input.Read(buffer, 0, bufferSize);
                if (bytesRead > 0)
                {
                    engine.ProcessBytes(buffer, 0, bytesRead, enc, 0);
                    output.Write(enc, 0, bytesRead);

                    if (notifyProgression != null)
                    {
                        notifyProgression(bytesRead);
                    }
                }
            } while (bytesRead == bufferSize);
        }
示例#2
0
        private void reinitBug()
        {
            KeyParameter     key        = new KeyParameter(Hex.Decode("80000000000000000000000000000000"));
            ParametersWithIV parameters = new ParametersWithIV(key, Hex.Decode("0000000000000000"));

            IStreamCipher salsa = new Salsa20Engine();

            salsa.Init(true, parameters);

            try
            {
                salsa.Init(true, key);
                Fail("Salsa20 should throw exception if no IV in Init");
            }
            catch (ArgumentException)
            {
            }
        }
示例#3
0
        private void salsa20Test1(
            int rounds,
            ICipherParameters parameters,
            string v0,
            string v192,
            string v256,
            string v448)
        {
            IStreamCipher salsa = new Salsa20Engine(rounds);

            byte[] buf = new byte[64];

            salsa.Init(true, parameters);

            for (int i = 0; i != 7; i++)
            {
                salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
                switch (i)
                {
                case 0:
                    if (!AreEqual(buf, Hex.Decode(v0)))
                    {
                        mismatch("v0/" + rounds, v0, buf);
                    }
                    break;

                case 3:
                    if (!AreEqual(buf, Hex.Decode(v192)))
                    {
                        mismatch("v192/" + rounds, v192, buf);
                    }
                    break;

                case 4:
                    if (!AreEqual(buf, Hex.Decode(v256)))
                    {
                        mismatch("v256/" + rounds, v256, buf);
                    }
                    break;

                default:
                    // ignore
                    break;
                }
            }

            for (int i = 0; i != 64; i++)
            {
                buf[i] = salsa.ReturnByte(zeroes[i]);
            }

            if (!AreEqual(buf, Hex.Decode(v448)))
            {
                mismatch("v448", v448, buf);
            }
        }
示例#4
0
        /// <summary>
        /// Decrypt data with Salsa20
        /// </summary>
        /// <param name="data">Data to decrypt</param>
        /// <param name="key">Key</param>
        /// <param name="nonce">Nonce</param>
        /// <returns>Decrypted data</returns>
        public static byte[] Decrypt(byte[] data, byte[] key, byte[] nonce)
        {
            byte[] dec = new byte[data.Length];

            Salsa20Engine    engine     = new Salsa20Engine();
            ParametersWithIV parameters = new ParametersWithIV(new KeyParameter(key, 0, key.Length), nonce, 0, nonce.Length);

            engine.Init(false, parameters);
            engine.ProcessBytes(data, 0, data.Length, dec, 0);

            return(dec);
        }
示例#5
0
        private byte[] SalsaB(byte[] Key, byte[] Vector, byte[] Data)
        {
            int len = Data.Length;
            int ct  = 0;

            byte[]        output = new byte[len];
            Salsa20Engine salsa  = new Salsa20Engine();

            salsa.Init(true, Key, Vector);

            while (ct < len)
            {
                salsa.ProcessBytes(Data, ct, 64, output, ct);
                ct += 64;
            }

            return(output);
        }
示例#6
0
        /// <summary>
        ///   Gets an ID for the key.
        /// </summary>
        /// <returns>
        ///   A byte array that can be used as an identifier for the key.
        /// </returns>
        /// <remarks>
        ///   C# implementation of the GO code at
        ///   <see href="https://github.com/libp2p/go-libp2p-pnet/blob/bed5e6afdf9099121029f6fb675be12a50196114/fingerprint.go#L10"/>.
        /// </remarks>
        public byte[] Fingerprint()
        {
            // Encrypt data first so we don't feed PSK to hash function.
            // Salsa20 function is not reversible thus increasing our security margin.
            var encrypted = new byte[64];
            var nonce     = Encoding.ASCII.GetBytes("finprint");
            var cipher    = new Salsa20Engine();

            cipher.Init(true, new ParametersWithIV(new KeyParameter(this.Value), nonce));
            cipher.ProcessBytes(encrypted, 0, encrypted.Length, encrypted, 0);

            // Then do Shake-128 hash to reduce its length.
            // This way if for some reason Shake is broken and Salsa20 preimage is possible,
            // attacker has only half of the bytes necessary to recreate psk.
            return(MultiHash
                   .GetHashAlgorithm("shake-128")
                   .ComputeHash(encrypted));
        }
示例#7
0
        private void salsa20Test2(
            ICipherParameters parameters,
            string v0,
            string v65472,
            string v65536)
        {
            IStreamCipher salsa = new Salsa20Engine();

            byte[] buf = new byte[64];

            salsa.Init(true, parameters);

            for (int i = 0; i != 1025; i++)
            {
                salsa.ProcessBytes(zeroes, 0, 64, buf, 0);
                switch (i)
                {
                case 0:
                    if (!AreEqual(buf, Hex.Decode(v0)))
                    {
                        mismatch("v0", v0, buf);
                    }
                    break;

                case 1023:
                    if (!AreEqual(buf, Hex.Decode(v65472)))
                    {
                        mismatch("v65472", v65472, buf);
                    }
                    break;

                case 1024:
                    if (!AreEqual(buf, Hex.Decode(v65536)))
                    {
                        mismatch("v65536", v65536, buf);
                    }
                    break;

                default:
                    // ignore
                    break;
                }
            }
        }
示例#8
0
        private byte[] Salsa2Test(byte[] Key, byte[] Vector, byte[] Data)
        {
            int len = Data.Length;
            int ct = 0;
            byte[] output = new byte[len];
            Salsa20Engine salsa = new Salsa20Engine();
            salsa.Init(true, Key, Vector);

            while (ct < len)
            {
                salsa.ProcessBytes(Data, ct, 64, output, ct);
                ct += 64;
            }

            return output;
        }