/// <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)); }
private void Compress(ReadOnlySpan <byte> data, uint finalizer) { var dataAsUInt = MemoryMarshal.Cast <byte, uint>(data); var h0 = m_h0; var h1 = m_h1; var h2 = m_h2; var h3 = m_h3; var h4 = m_h4; var r0 = m_r0; var r1 = m_r1; var r2 = m_r2; var r3 = m_r3; var r4 = m_r4; var s0 = m_s0; var s1 = m_s1; var s2 = m_s2; var s3 = m_s3; var t0 = dataAsUInt[0]; var t1 = dataAsUInt[1]; var t2 = dataAsUInt[2]; var t3 = dataAsUInt[3]; h0 += (t0 & 0x3FFFFFFU); h1 += ((uint)((BitwiseHelpers.ConcatBits(t1, t0) >> 26) & 0x3FFFFFFU)); h2 += ((uint)((BitwiseHelpers.ConcatBits(t2, t1) >> 20) & 0x3FFFFFFU)); h3 += ((uint)((BitwiseHelpers.ConcatBits(t3, t2) >> 14) & 0x3FFFFFFU)); h4 += ((uint)BitwiseHelpers.Add((t3 >> 8), finalizer)); var d0 = (BitwiseHelpers.Multiply(h0, r0) + BitwiseHelpers.Multiply(h1, s3) + BitwiseHelpers.Multiply(h2, s2) + BitwiseHelpers.Multiply(h3, s1) + BitwiseHelpers.Multiply(h4, s0)); var d1 = (BitwiseHelpers.Multiply(h0, r1) + BitwiseHelpers.Multiply(h1, r0) + BitwiseHelpers.Multiply(h2, s3) + BitwiseHelpers.Multiply(h3, s2) + BitwiseHelpers.Multiply(h4, s1)); var d2 = (BitwiseHelpers.Multiply(h0, r2) + BitwiseHelpers.Multiply(h1, r1) + BitwiseHelpers.Multiply(h2, r0) + BitwiseHelpers.Multiply(h3, s3) + BitwiseHelpers.Multiply(h4, s2)); var d3 = (BitwiseHelpers.Multiply(h0, r3) + BitwiseHelpers.Multiply(h1, r2) + BitwiseHelpers.Multiply(h2, r1) + BitwiseHelpers.Multiply(h3, r0) + BitwiseHelpers.Multiply(h4, s3)); var d4 = (BitwiseHelpers.Multiply(h0, r4) + BitwiseHelpers.Multiply(h1, r3) + BitwiseHelpers.Multiply(h2, r2) + BitwiseHelpers.Multiply(h3, r1) + BitwiseHelpers.Multiply(h4, r0)); var c = (d0 >> 26); h0 = ((uint)(d0 & 0x3FFFFFFU)); d1 += c; c = (d1 >> 26); h1 = ((uint)(d1 & 0x3FFFFFFU)); d2 += c; c = (d2 >> 26); h2 = ((uint)(d2 & 0x3FFFFFFU)); d3 += c; c = (d3 >> 26); h3 = ((uint)(d3 & 0x3FFFFFFU)); d4 += c; c = (d4 >> 26); h4 = ((uint)(d4 & 0x3FFFFFFU)); h0 += ((uint)(c * 5UL)); c = (h0 >> 26); h0 = (h0 & 0x3FFFFFFU); h1 += ((uint)c); m_h0 = h0; m_h1 = h1; m_h2 = h2; m_h3 = h3; m_h4 = h4; }
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); }