Esempio n. 1
0
        /// <summary>
        /// Creates a symmetric decryptor object with the current Key property and one-time use state parameter.
        /// </summary>
        /// <param name="key">The secret that will be used during decryption.</param>
        /// <param name="nonce">The one-time use state parameter.</param>
        public override ICryptoTransform CreateDecryptor(byte[] key, byte[] nonce)
        {
            var ivLow  = m_iv;
            var ivHigh = BinaryPrimitives.ReadUInt32LittleEndian(nonce.AsSpan(0, ChaChaTransform.WordLength));

            return(ChaChaTransform.New(Initialize(key, nonce, ivLow), BitwiseHelpers.ConcatBits(ivHigh, ivLow), 20U));
        }
Esempio n. 2
0
        public static byte[] GenerateOneTimeKey(ReadOnlySpan <byte> key, ReadOnlySpan <byte> nonce, uint numRounds)
        {
            var ivLow      = 0U;
            var ivHigh     = BinaryPrimitives.ReadUInt32LittleEndian(nonce);
            var oneTimeKey = new byte[ChaChaTransform.BlockLength];

            ChaChaTransform.WriteKeyStreamBlock(ChaCha.Initialize(key, nonce, ivLow), BitwiseHelpers.ConcatBits(ivHigh, ivLow), numRounds, oneTimeKey);

            return(oneTimeKey);
        }
Esempio n. 3
0
        /// <summary>
        /// Computes a hash of the key and nonce using the HChaCha algorithm.
        /// </summary>
        /// <param name="key">The secret that will be used during decryption.</param>
        /// <param name="nonce">The one-time use state parameter.</param>
        public static byte[] ComputeHash(ReadOnlySpan <byte> key, ReadOnlySpan <byte> nonce)
        {
            var hash       = new byte[(ChaChaTransform.BlockLength >> 1)];
            var hashAsUInt = MemoryMarshal.Cast <byte, uint>(hash);
            var state      = Initialize(key, nonce.Slice(ChaChaTransform.WordLength), BinaryPrimitives.ReadUInt32LittleEndian(nonce.Slice(0, ChaChaTransform.WordLength)));
            var stateSpan  = state.AsSpan();
            var t0         = state[0];
            var t1         = state[1];
            var t2         = state[2];
            var t3         = state[3];
            var t4         = state[4];
            var t5         = state[5];
            var t6         = state[6];
            var t7         = state[7];
            var t8         = state[8];
            var t9         = state[9];
            var tA         = state[10];
            var tB         = state[11];
            var tC         = state[12];
            var tD         = state[13];
            var tE         = state[14];
            var tF         = state[15];

            for (var i = 0U; (i < 10U); i++)
            {
                ChaChaTransform.DoubleRound(
                    ref t0, ref t1, ref t2, ref t3,
                    ref t4, ref t5, ref t6, ref t7,
                    ref t8, ref t9, ref tA, ref tB,
                    ref tC, ref tD, ref tE, ref tF
                    );
            }

            state[0]  = t0;
            state[1]  = t1;
            state[2]  = t2;
            state[3]  = t3;
            state[4]  = t4;
            state[5]  = t5;
            state[6]  = t6;
            state[7]  = t7;
            state[8]  = t8;
            state[9]  = t9;
            state[10] = tA;
            state[11] = tB;
            state[12] = tC;
            state[13] = tD;
            state[14] = tE;
            state[15] = tF;

            stateSpan.Slice(0, ChaChaTransform.WordLength).CopyTo(hashAsUInt.Slice(0, ChaChaTransform.WordLength));
            stateSpan.Slice((ChaChaTransform.NumWordsPerBlock - ChaChaTransform.WordLength), ChaChaTransform.WordLength).CopyTo(hashAsUInt.Slice(ChaChaTransform.WordLength));

            return(hash);
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a symmetric decryptor object with the current Key property and one-time use state parameter.
        /// </summary>
        /// <param name="key">The secret that will be used during decryption.</param>
        /// <param name="nonce">The one-time use state parameter.</param>
        public override ICryptoTransform CreateDecryptor(byte[] key, byte[] nonce)
        {
            var ivLow = ((uint)BitwiseHelpers.ExtractLow(m_iv));

            return(ChaChaTransform.New(Initialize(key, nonce, ivLow), m_iv, 20U));
        }