/// <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, WordLength)); return(ChaChaTransform.New(Initialize(key, nonce, m_iv), Operations.ConcatBits(ivHigh, ivLow), 20U)); }
/// <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) { if (nonce.Length != XChaCha20.NonceLength) { throw new ArgumentOutOfRangeException(actualValue: nonce.Length, message: NONCE_LENGTH_ERROR, paramName: nameof(nonce)); } var derivedKey = ComputeHash(key, nonce.AsSpan(0, 16)); var derivedNonce = (Span <byte>) stackalloc byte[ChaCha.NonceLength]; BinaryPrimitives.WriteUInt32BigEndian(derivedNonce, ((uint)Operations.ExtractHigh(m_iv))); nonce.AsSpan(16, 8).CopyTo(derivedNonce.Slice(WordLength)); return(ChaChaTransform.New(Initialize(derivedKey, derivedNonce, ((uint)Operations.ExtractLow(m_iv))), m_iv, 20U)); }