├── _config.yml ├── SECURITY.md ├── src ├── ChaCha20-BLAKE3 │ ├── bin │ │ └── Release │ │ │ ├── vcruntime (x64) │ │ │ └── vcruntime140.dll │ │ │ └── vcruntime (x86) │ │ │ └── vcruntime140.dll │ ├── Constants.cs │ ├── BitConversion.cs │ ├── Arrays.cs │ ├── ChaCha20-BLAKE3.csproj │ ├── KeyDerivation.cs │ ├── Tag.cs │ ├── ParameterValidation.cs │ ├── ChaCha20BLAKE3.cs │ ├── XChaCha20BLAKE3.cs │ └── XChaCha20BLAKE3SIV.cs └── ChaCha20-BLAKE3.sln ├── LICENSE ├── .github └── workflows │ └── codeql-analysis.yml └── README.md /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting a vulnerability 2 | Please email me at `samuel[at]samuellucas[dot]com` using an informative subject line that references the name of this project. 3 | -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/bin/Release/vcruntime (x64)/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuel-lucas6/ChaCha20-BLAKE3/HEAD/src/ChaCha20-BLAKE3/bin/Release/vcruntime (x64)/vcruntime140.dll -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/bin/Release/vcruntime (x86)/vcruntime140.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/samuel-lucas6/ChaCha20-BLAKE3/HEAD/src/ChaCha20-BLAKE3/bin/Release/vcruntime (x86)/vcruntime140.dll -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2022 Samuel Lucas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31019.35 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChaCha20-BLAKE3", "ChaCha20-BLAKE3\ChaCha20-BLAKE3.csproj", "{129A5471-2792-4515-8EEB-74B8417D21C0}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {129A5471-2792-4515-8EEB-74B8417D21C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {129A5471-2792-4515-8EEB-74B8417D21C0}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {129A5471-2792-4515-8EEB-74B8417D21C0}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {129A5471-2792-4515-8EEB-74B8417D21C0}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {E983BC8F-27E3-44F1-AB8A-CB9AFE8FBEA1} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/Constants.cs: -------------------------------------------------------------------------------- 1 | /* 2 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 3 | Copyright (c) 2021-2022 Samuel Lucas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | */ 23 | 24 | namespace ChaCha20Blake3 25 | { 26 | internal static class Constants 27 | { 28 | internal const int KeySize = 32; 29 | internal const int ChaChaNonceSize = 8; 30 | internal const int XChaChaNonceSize = 24; 31 | internal const int TagSize = 32; 32 | } 33 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/BitConversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /* 4 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 5 | Copyright (c) 2021-2022 Samuel Lucas 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | the Software, and to permit persons to whom the Software is furnished to do so, 12 | subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | namespace ChaCha20Blake3 27 | { 28 | internal static class BitConversion 29 | { 30 | public static byte[] GetBytes(int value) 31 | { 32 | var valueBytes = BitConverter.GetBytes(value); 33 | if (!BitConverter.IsLittleEndian) { Array.Reverse(valueBytes); } 34 | return valueBytes; 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/Arrays.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | /* 5 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 6 | Copyright (c) 2021-2022 Samuel Lucas 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 12 | the Software, and to permit persons to whom the Software is furnished to do so, 13 | subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | namespace ChaCha20Blake3 28 | { 29 | internal static class Arrays 30 | { 31 | internal static T[] Concat(params T[][] arrays) 32 | { 33 | int offset = 0; 34 | var result = new T[arrays.Sum(array => array.Length)]; 35 | foreach (var array in arrays) 36 | { 37 | Array.Copy(array, sourceIndex: 0, result, offset, array.Length); 38 | offset += array.Length; 39 | } 40 | return result; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/ChaCha20-BLAKE3.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.1 5 | ChaCha20Blake3 6 | ChaCha20BLAKE3 7 | Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV implementations. 8 | Samuel Lucas 9 | Copyright (c) 2021-2022 Samuel Lucas 10 | MIT 11 | https://github.com/samuel-lucas6/ChaCha20-BLAKE3 12 | https://github.com/samuel-lucas6/ChaCha20-BLAKE3 13 | true 14 | true 15 | true 16 | true 17 | 3.0.0 18 | 3.0.0.0 19 | 3.0.0.0 20 | latest 21 | none 22 | git 23 | libsodium cryptography crypto encryption authenticated-encryption aead Encrypt-then-MAC ChaCha20-BLAKE3 XChaCha20-BLAKE3 XChaCha20-BLAKE3-SIV ChaCha20 XChaCha20 BLAKE3 SIV 24 | 25 | 26 | 27 | AnyCPU 28 | 29 | 30 | 31 | AnyCPU 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/KeyDerivation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Blake3; 3 | 4 | /* 5 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 6 | Copyright (c) 2021-2022 Samuel Lucas 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 12 | the Software, and to permit persons to whom the Software is furnished to do so, 13 | subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | namespace ChaCha20Blake3 28 | { 29 | internal static class KeyDerivation 30 | { 31 | internal static (byte[] encryptionKey, byte[] macKey) DeriveKeys(byte[] inputKeyingMaterial, byte[] encryptionContext, byte[] authenticationContext, byte[] nonce = null) 32 | { 33 | byte[] encryptionKey = DeriveKey(inputKeyingMaterial, encryptionContext); 34 | byte[] macKey = DeriveKey(inputKeyingMaterial, authenticationContext, nonce); 35 | return (encryptionKey, macKey); 36 | } 37 | 38 | private static byte[] DeriveKey(byte[] inputKeyingMaterial, byte[] context, byte[] salt = null) 39 | { 40 | salt ??= Array.Empty(); 41 | using var blake3 = Hasher.NewDeriveKey(context); 42 | blake3.Update(salt); 43 | blake3.Update(inputKeyingMaterial); 44 | blake3.Update(BitConversion.GetBytes(salt.Length)); 45 | blake3.Update(BitConversion.GetBytes(inputKeyingMaterial.Length)); 46 | var key = blake3.Finalize(); 47 | return key.AsSpanUnsafe().ToArray(); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '42 20 * * 3' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'csharp' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/Tag.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Blake3; 3 | 4 | /* 5 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 6 | Copyright (c) 2021-2022 Samuel Lucas 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy of 9 | this software and associated documentation files (the "Software"), to deal in 10 | the Software without restriction, including without limitation the rights to 11 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 12 | the Software, and to permit persons to whom the Software is furnished to do so, 13 | subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | namespace ChaCha20Blake3 28 | { 29 | internal static class Tag 30 | { 31 | internal static byte[] Compute(byte[] additionalData, byte[] ciphertext, byte[] macKey) 32 | { 33 | var message = Arrays.Concat(additionalData, ciphertext, BitConversion.GetBytes(additionalData.Length), BitConversion.GetBytes(ciphertext.Length)); 34 | using var blake3 = Hasher.NewKeyed(macKey); 35 | blake3.UpdateWithJoin(message); 36 | var tag = blake3.Finalize(); 37 | return tag.AsSpanUnsafe().ToArray(); 38 | } 39 | 40 | internal static byte[] Read(byte[] ciphertext, out byte[] ciphertextWithoutTag) 41 | { 42 | var tag = new byte[Constants.TagSize]; 43 | Array.Copy(ciphertext, ciphertext.Length - tag.Length, tag, destinationIndex: 0, tag.Length); 44 | ciphertextWithoutTag = Remove(ciphertext); 45 | return tag; 46 | } 47 | 48 | private static byte[] Remove(byte[] ciphertextWithTag) 49 | { 50 | var ciphertext = new byte[ciphertextWithTag.Length - Constants.TagSize]; 51 | Array.Copy(ciphertextWithTag, sourceIndex: 0, ciphertext, destinationIndex: 0, ciphertext.Length); 52 | return ciphertext; 53 | } 54 | 55 | internal static byte[] GetNonce(byte[] tag) 56 | { 57 | var nonce = new byte[Constants.XChaChaNonceSize]; 58 | Array.Copy(tag, nonce, nonce.Length); 59 | return nonce; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/ParameterValidation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | /* 4 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 5 | Copyright (c) 2021-2022 Samuel Lucas 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy of 8 | this software and associated documentation files (the "Software"), to deal in 9 | the Software without restriction, including without limitation the rights to 10 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 11 | the Software, and to permit persons to whom the Software is furnished to do so, 12 | subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | */ 25 | 26 | namespace ChaCha20Blake3 27 | { 28 | internal static class ParameterValidation 29 | { 30 | internal static byte[] AdditionalData(byte[] additionalData) => additionalData ?? Array.Empty(); 31 | 32 | internal static void Message(byte[] message) 33 | { 34 | if (message == null) { throw new ArgumentNullException(nameof(message), "The message cannot be null."); } 35 | if (message.Length == 0) { throw new ArgumentOutOfRangeException(nameof(message), $"The message cannot be empty."); } 36 | } 37 | 38 | internal static void Ciphertext(byte[] ciphertext) 39 | { 40 | if (ciphertext == null) { throw new ArgumentNullException(nameof(ciphertext), "The ciphertext cannot be null."); } 41 | if (ciphertext.Length <= Constants.TagSize) { throw new ArgumentOutOfRangeException(nameof(ciphertext), ciphertext.Length, $"The ciphertext must be at least {Constants.TagSize + 1} bytes in length."); } 42 | } 43 | 44 | internal static void Nonce(byte[] nonce, int validNonceLength) 45 | { 46 | if (nonce == null) { throw new ArgumentNullException(nameof(nonce), "The nonce cannot be null."); } 47 | if (nonce.Length != validNonceLength) { throw new ArgumentOutOfRangeException(nameof(nonce), nonce.Length, $"The nonce must be {validNonceLength} bytes in length."); } 48 | } 49 | 50 | internal static void Key(byte[] key, int validKeyLength) 51 | { 52 | if (key == null) { throw new ArgumentNullException(nameof(key), "The key cannot be null."); } 53 | if (key.Length != validKeyLength) { throw new ArgumentOutOfRangeException(nameof(key), key.Length, $"The key must be {validKeyLength} bytes in length."); } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/ChaCha20BLAKE3.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Security.Cryptography; 3 | using Sodium; 4 | 5 | /* 6 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 7 | Copyright (c) 2021-2022 Samuel Lucas 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of 10 | this software and associated documentation files (the "Software"), to deal in 11 | the Software without restriction, including without limitation the rights to 12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 13 | the Software, and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | namespace ChaCha20Blake3 29 | { 30 | public static class ChaCha20BLAKE3 31 | { 32 | public const int KeySize = Constants.KeySize; 33 | public const int NonceSize = Constants.ChaChaNonceSize; 34 | public const int TagSize = Constants.TagSize; 35 | private static readonly byte[] EncryptionContext = Encoding.UTF8.GetBytes("ChaCha20-BLAKE3 16/12/2021 14:08 ChaCha20.Encrypt()"); 36 | private static readonly byte[] AuthenticationContext = Encoding.UTF8.GetBytes("ChaCha20-BLAKE3 16/12/2021 14:09 BLAKE3.KeyedHash()"); 37 | 38 | public static byte[] Encrypt(byte[] message, byte[] nonce, byte[] key, byte[] additionalData = null) 39 | { 40 | ParameterValidation.Message(message); 41 | ParameterValidation.Nonce(nonce, NonceSize); 42 | ParameterValidation.Key(key, KeySize); 43 | additionalData = ParameterValidation.AdditionalData(additionalData); 44 | (byte[] encryptionKey, byte[] macKey) = KeyDerivation.DeriveKeys(key, EncryptionContext, AuthenticationContext, nonce); 45 | byte[] ciphertext = StreamEncryption.EncryptChaCha20(message, nonce, encryptionKey); 46 | byte[] tag = Tag.Compute(additionalData, ciphertext, macKey); 47 | return Arrays.Concat(ciphertext, tag); 48 | } 49 | 50 | public static byte[] Decrypt(byte[] ciphertext, byte[] nonce, byte[] key, byte[] additionalData = null) 51 | { 52 | ParameterValidation.Ciphertext(ciphertext); 53 | ParameterValidation.Nonce(nonce, NonceSize); 54 | ParameterValidation.Key(key, KeySize); 55 | additionalData = ParameterValidation.AdditionalData(additionalData); 56 | (byte[] encryptionKey, byte[] macKey) = KeyDerivation.DeriveKeys(key, EncryptionContext, AuthenticationContext, nonce); 57 | byte[] tag = Tag.Read(ciphertext, out byte[] ciphertextWithoutTag); 58 | byte[] computedTag = Tag.Compute(additionalData, ciphertextWithoutTag, macKey); 59 | bool validTag = Utilities.Compare(tag, computedTag); 60 | return !validTag ? throw new CryptographicException() : StreamEncryption.DecryptChaCha20(ciphertextWithoutTag, nonce, encryptionKey); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/XChaCha20BLAKE3.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Security.Cryptography; 3 | using Sodium; 4 | 5 | /* 6 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 7 | Copyright (c) 2021-2022 Samuel Lucas 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of 10 | this software and associated documentation files (the "Software"), to deal in 11 | the Software without restriction, including without limitation the rights to 12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 13 | the Software, and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | namespace ChaCha20Blake3 29 | { 30 | public static class XChaCha20BLAKE3 31 | { 32 | public const int KeySize = Constants.KeySize; 33 | public const int NonceSize = Constants.XChaChaNonceSize; 34 | public const int TagSize = Constants.TagSize; 35 | private static readonly byte[] EncryptionContext = Encoding.UTF8.GetBytes("XChaCha20-BLAKE3 16/12/2021 14:51 XChaCha20.Encrypt()"); 36 | private static readonly byte[] AuthenticationContext = Encoding.UTF8.GetBytes("XChaCha20-BLAKE3 16/12/2021 14:52 BLAKE3.KeyedHash()"); 37 | 38 | public static byte[] Encrypt(byte[] message, byte[] nonce, byte[] key, byte[] additionalData = null) 39 | { 40 | ParameterValidation.Message(message); 41 | ParameterValidation.Nonce(nonce, NonceSize); 42 | ParameterValidation.Key(key, KeySize); 43 | additionalData = ParameterValidation.AdditionalData(additionalData); 44 | (byte[] encryptionKey, byte[] macKey) = KeyDerivation.DeriveKeys(key, EncryptionContext, AuthenticationContext, nonce); 45 | byte[] ciphertext = StreamEncryption.EncryptXChaCha20(message, nonce, encryptionKey); 46 | byte[] tag = Tag.Compute(additionalData, ciphertext, macKey); 47 | return Arrays.Concat(ciphertext, tag); 48 | } 49 | 50 | public static byte[] Decrypt(byte[] ciphertext, byte[] nonce, byte[] key, byte[] additionalData = null) 51 | { 52 | ParameterValidation.Ciphertext(ciphertext); 53 | ParameterValidation.Nonce(nonce, NonceSize); 54 | ParameterValidation.Key(key, KeySize); 55 | additionalData = ParameterValidation.AdditionalData(additionalData); 56 | (byte[] encryptionKey, byte[] macKey) = KeyDerivation.DeriveKeys(key, EncryptionContext, AuthenticationContext, nonce); 57 | byte[] tag = Tag.Read(ciphertext, out byte[] ciphertextWithoutTag); 58 | byte[] computedTag = Tag.Compute(additionalData, ciphertextWithoutTag, macKey); 59 | bool validTag = Utilities.Compare(tag, computedTag); 60 | return !validTag ? throw new CryptographicException() : StreamEncryption.DecryptXChaCha20(ciphertextWithoutTag, nonce, encryptionKey); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /src/ChaCha20-BLAKE3/XChaCha20BLAKE3SIV.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using System.Security.Cryptography; 3 | using Sodium; 4 | 5 | /* 6 | ChaCha20-BLAKE3: Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations. 7 | Copyright (c) 2021-2022 Samuel Lucas 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of 10 | this software and associated documentation files (the "Software"), to deal in 11 | the Software without restriction, including without limitation the rights to 12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 13 | the Software, and to permit persons to whom the Software is furnished to do so, 14 | subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | */ 27 | 28 | namespace ChaCha20Blake3 29 | { 30 | public static class XChaCha20BLAKE3SIV 31 | { 32 | public const int KeySize = Constants.KeySize; 33 | public const int TagSize = Constants.TagSize; 34 | private static readonly byte[] EncryptionContext = Encoding.UTF8.GetBytes("XChaCha20-BLAKE3-SIV 16/12/2021 14:54 XChaCha20.Encrypt()"); 35 | private static readonly byte[] AuthenticationContext = Encoding.UTF8.GetBytes("XChaCha20-BLAKE3-SIV 16/12/2021 14:55 BLAKE3.KeyedHash()"); 36 | 37 | public static byte[] Encrypt(byte[] message, byte[] key, byte[] additionalData = null) 38 | { 39 | ParameterValidation.Message(message); 40 | ParameterValidation.Key(key, KeySize); 41 | additionalData = ParameterValidation.AdditionalData(additionalData); 42 | (byte[] encryptionKey, byte[] macKey) = KeyDerivation.DeriveKeys(key, EncryptionContext, AuthenticationContext); 43 | byte[] tag = Tag.Compute(additionalData, message, macKey); 44 | byte[] nonce = Tag.GetNonce(tag); 45 | byte[] ciphertext = StreamEncryption.EncryptXChaCha20(message, nonce, encryptionKey); 46 | return Arrays.Concat(ciphertext, tag); 47 | } 48 | 49 | public static byte[] Decrypt(byte[] ciphertext, byte[] key, byte[] additionalData = null) 50 | { 51 | ParameterValidation.Ciphertext(ciphertext); 52 | ParameterValidation.Key(key, KeySize); 53 | additionalData = ParameterValidation.AdditionalData(additionalData); 54 | (byte[] encryptionKey, byte[] macKey) = KeyDerivation.DeriveKeys(key, EncryptionContext, AuthenticationContext); 55 | byte[] tag = Tag.Read(ciphertext, out byte[] ciphertextWithoutTag); 56 | byte[] nonce = Tag.GetNonce(tag); 57 | byte[] message = StreamEncryption.DecryptXChaCha20(ciphertextWithoutTag, nonce, encryptionKey); 58 | byte[] computedTag = Tag.Compute(additionalData, message, macKey); 59 | bool validTag = Utilities.Compare(tag, computedTag); 60 | if (validTag) { return message; } 61 | CryptographicOperations.ZeroMemory(message); 62 | CryptographicOperations.ZeroMemory(computedTag); 63 | throw new CryptographicException(); 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/samuel-lucas6/ChaCha20-BLAKE3/blob/main/LICENSE) 2 | [![CodeQL](https://github.com/samuel-lucas6/ChaCha20-BLAKE3/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/samuel-lucas6/ChaCha20-BLAKE3/actions) 3 | 4 | # ChaCha20-BLAKE3 5 | Committing ChaCha20-BLAKE3, XChaCha20-BLAKE3, and XChaCha20-BLAKE3-SIV AEAD implementations using [libsodium](https://doc.libsodium.org/) and [BLAKE3](https://github.com/BLAKE3-team/BLAKE3). 6 | 7 | ## Features 8 | This library does several things for you: 9 | - Derives a 256-bit encryption key and 256-bit MAC key based on the key and nonce. 10 | - Supports additional data in the calculation of the authentication tag, unlike most Encrypt-then-MAC implementations. 11 | - Appends the authentication tag to the ciphertext. 12 | - Compares the authentication tags in constant time during decryption and only returns plaintext if they match. 13 | - Offers access to an SIV implementation that does not take a nonce. 14 | 15 | ## Justification 16 | The popular AEADs in use today, such as (X)ChaCha20-Poly1305, AES-GCM, AES-GCM-SIV, XSalsa20-Poly1305, AES-OCB, and so on, are not key or message committing. This means it is possible to decrypt a ciphertext using [multiple keys](https://youtu.be/3M1jIO-jLHI) without an authentication error, which can lead to [partitioning oracle attacks](https://eprint.iacr.org/2020/1491.pdf) and [deanonymisation](https://github.com/LoupVaillant/Monocypher/issues/218#issuecomment-886997371) in certain online scenarios. Furthermore, if an attacker knows the key, then they can find other messages that have the [same tag](https://neilmadden.blog/2021/02/16/when-a-kem-is-not-enough/). 17 | 18 | This library was created because there are currently no standardised committing AEAD schemes, adding the commitment property to a non-committing AEAD requires using a MAC, and Encrypt-then-MAC offers improved security guarantees. 19 | 20 | Finally, (X)ChaCha20-BLAKE3 is a good combination for an Encrypt-then-MAC scheme because: 21 | 1. ChaCha20 has a [higher security margin](https://eprint.iacr.org/2019/1492.pdf) than AES, performs well on older devices, and runs in [constant time](https://cr.yp.to/chacha/chacha-20080128.pdf), [unlike](https://cr.yp.to/antiforgery/cachetiming-20050414.pdf) AES. 22 | 2. BLAKE3 is [fast](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf) and evolved from BLAKE, which received a [significant amount of cryptanalysis](https://nvlpubs.nist.gov/nistpubs/ir/2012/NIST.IR.7896.pdf), even more than Keccak (the SHA3 finalist), as part of the [SHA3 competition](https://competitions.cr.yp.to/sha3.html). 23 | 24 | ## Installation 25 | ### NuGet 26 | You can find the NuGet package [here](https://www.nuget.org/packages/ChaCha20BLAKE3). The easiest way to install this is via the NuGet Package Manager in [Visual Studio](https://visualstudio.microsoft.com/vs/), as explained [here](https://docs.microsoft.com/en-us/nuget/quickstart/install-and-use-a-package-in-visual-studio). [JetBrains Rider](https://www.jetbrains.com/rider/) also has a package manager, and instructions can be found [here](https://www.jetbrains.com/help/rider/Using_NuGet.html). 27 | 28 | ### Manual 29 | 1. Install the [Sodium.Core](https://www.nuget.org/packages/Sodium.Core) and [Blake3.NET](https://www.nuget.org/packages/Blake3/) NuGet packages for your project in [Visual Studio](https://docs.microsoft.com/en-us/nuget/quickstart/install-and-use-a-package-in-visual-studio). 30 | 2. Download the latest [release](https://github.com/samuel-lucas6/ChaCha20-BLAKE3/releases/latest). 31 | 3. Move the downloaded `.dll` file into your project folder. 32 | 4. Click on the `Project` tab and `Add Project Reference...` in Visual Studio. 33 | 5. Go to `Browse`, click the `Browse` button, and select the downloaded `.dll` file. 34 | 6. Add `using ChaCha20Blake3;` to the top of each code file that will use the library. 35 | 36 | ### Notes 37 | The [libsodium](https://doc.libsodium.org/) library requires the [Visual C++ Redistributable for Visual Studio 2015-2019](https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads) to work on Windows. If you want your program to be portable, then you must keep the relevant (x86 or x64) `vcruntime140.dll` file in the same folder as your executable on Windows. 38 | 39 | ## Usage 40 | ### ChaCha20-BLAKE3 41 | ⚠️**WARNING: Never reuse a nonce with the same key.** 42 | ```c# 43 | const string filePath = "C:\\Users\\samuel-lucas6\\Pictures\\test.jpg"; 44 | const string version = "application v1.0.0"; 45 | 46 | // The message does not have to be a file 47 | byte[] message = File.ReadAllBytes(filePath); 48 | 49 | // The nonce should be a counter that gets incremented for each message encrypted using the same key 50 | byte[] nonce = new byte[ChaCha20BLAKE3.NonceSize]; 51 | 52 | // The key can be randomly generated using a CSPRNG or derived using a KDF (e.g. Argon2, HKDF, etc) 53 | byte[] key = SodiumCore.GetRandomBytes(ChaCha20BLAKE3.KeySize); 54 | 55 | // The additional data can be null but is ideal for file headers, version numbers, timestamps, etc 56 | byte[] additionalData = Encoding.UTF8.GetBytes(version); 57 | 58 | // Encrypt the message 59 | byte[] ciphertext = ChaCha20BLAKE3.Encrypt(message, nonce, key, additionalData); 60 | 61 | // Decrypt the ciphertext 62 | byte[] plaintext = ChaCha20BLAKE3.Decrypt(ciphertext, nonce, key, additionalData); 63 | ``` 64 | 65 | ### XChaCha20-BLAKE3 66 | ⚠️**WARNING: Never reuse a nonce with the same key.** 67 | ```c# 68 | const string filePath = "C:\\Users\\samuel-lucas6\\Pictures\\test.jpg"; 69 | const string version = "application v1.0.0"; 70 | 71 | // The message does not have to be a file 72 | byte[] message = File.ReadAllBytes(filePath); 73 | 74 | // The nonce can be a counter or randomly generated using a CSPRNG 75 | // Increment or randomly generate the nonce for each message encrypted using the same key 76 | byte[] nonce = SodiumCore.GetRandomBytes(XChaCha20BLAKE3.NonceSize); 77 | 78 | // The key can be randomly generated using a CSPRNG or derived using a KDF (e.g. Argon2, HKDF, etc) 79 | byte[] key = SodiumCore.GetRandomBytes(XChaCha20BLAKE3.KeySize); 80 | 81 | // The additional data can be null but is ideal for file headers, version numbers, timestamps, etc 82 | byte[] additionalData = Encoding.UTF8.GetBytes(version); 83 | 84 | // Encrypt the message 85 | byte[] ciphertext = XChaCha20BLAKE3.Encrypt(message, nonce, key, additionalData); 86 | 87 | // Decrypt the ciphertext 88 | byte[] plaintext = XChaCha20BLAKE3.Decrypt(ciphertext, nonce, key, additionalData); 89 | ``` 90 | 91 | ### XChaCha20-BLAKE3-SIV 92 | ⚠️**WARNING: Never reuse a key. As a precaution, you can use at least 16 bytes of unique, random data as part of the additional data to act as a nonce.** 93 | ```c# 94 | const string filePath = "C:\\Users\\samuel-lucas6\\Pictures\\test.jpg"; 95 | 96 | // The message does not have to be a file 97 | byte[] message = File.ReadAllBytes(filePath); 98 | 99 | // The key can be randomly generated using a CSPRNG or derived using a KDF (e.g. Argon2, HKDF, etc) 100 | byte[] key = SodiumCore.GetRandomBytes(XChaCha20BLAKE3SIV.KeySize); 101 | 102 | // The additional data can be null, used as a nonce, and/or used for file headers, version numbers, timestamps, etc 103 | byte[] additionalData = SodiumCore.GetRandomBytes(XChaCha20BLAKE3SIV.KeySize / 2); 104 | 105 | // Encrypt the message 106 | byte[] ciphertext = XChaCha20BLAKE3SIV.Encrypt(message, key, additionalData); 107 | 108 | // Decrypt the ciphertext 109 | byte[] plaintext = XChaCha20BLAKE3SIV.Decrypt(ciphertext, key, additionalData); 110 | ``` 111 | 112 | ## Benchmarks 113 | The following benchmarks were done using [BenchmarkDotNet](https://benchmarkdotnet.org/) in a [.NET 6](https://dotnet.microsoft.com/en-us/download/dotnet/6.0) console application with 16 bytes of additional data. 114 | 115 | In sum, ChaCha20-BLAKE3 performs similarly to ChaCha20-Poly1305 and is even faster with large inputs. Whilst it is slower with small messages, I would argue that the additional security makes up for any performance loss. 116 | 117 | #### 512 bytes 118 | | Method | Mean | Error | StdDev | 119 | |:--------------------------:|:--------:|:--------:|:--------:| 120 | | ChaCha20-BLAKE3.Encrypt | 1.504 us | 0.0027 us | 0.0024 us | 121 | | ChaCha20-BLAKE3.Decrypt | 1.530 us | 0.0067 us | 0.0060 us | 122 | | XChaCha20-BLAKE3.Encrypt | 1.601 us | 0.0012 us | 0.0010 us | 123 | | XChaCha20-BLAKE3.Decrypt | 1.610 us | 0.0068 us | 0.0060 us | 124 | | XChaCha20-BLAKE3-SIV.Encrypt | 1.593 us | 0.0086 us | 0.0080 us | 125 | | XChaCha20-BLAKE3-SIV.Decrypt | 1.610 us | 0.0009 us | 0.0008 us | 126 | | ChaCha20-Poly1305.Encrypt | 785.9 ns | 4.59 ns | 4.29 ns | 127 | | ChaCha20-Poly1305.Decrypt | 793.6 ns | 1.25 ns | 0.98 ns | 128 | | XChaCha20-Poly1305.Encrypt | 865.1 ns | 1.24 ns | 0.97 ns | 129 | | XChaCha20-Poly1305.Decrypt | 888.1 ns | 4.23 ns | 3.75 ns | 130 | 131 | #### 16 KiB 132 | | Method | Mean | Error | StdDev | 133 | |:--------------------------:|:--------:|:--------:|:--------:| 134 | | ChaCha20-BLAKE3.Encrypt | 25.49 us | 0.039 us | 0.032 us | 135 | | ChaCha20-BLAKE3.Decrypt | 24.91 us | 0.026 us | 0.024 us | 136 | | XChaCha20-BLAKE3.Encrypt | 25.75 us | 0.042 us | 0.039 us | 137 | | XChaCha20-BLAKE3.Decrypt | 24.99 us | 0.051 us | 0.048 us | 138 | | XChaCha20-BLAKE3-SIV.Encrypt | 23.76 us | 0.030 us | 0.028 us | 139 | | XChaCha20-BLAKE3-SIV.Decrypt | 23.88 us | 0.024 us | 0.022 us | 140 | | ChaCha20-Poly1305.Encrypt | 16.62 us | 0.049 us | 0.041 us | 141 | | ChaCha20-Poly1305.Decrypt | 16.66 us | 0.096 us | 0.090 us | 142 | | XChaCha20-Poly1305.Encrypt | 16.76 us | 0.069 us | 0.058 us | 143 | | XChaCha20-Poly1305.Decrypt | 16.70 us | 0.020 us | 0.017 us | 144 | 145 | #### 32 KiB 146 | | Method | Mean | Error | StdDev | 147 | |:--------------------------:|:--------:|:--------:|:--------:| 148 | | ChaCha20-BLAKE3.Encrypt | 40.38 us | 0.060 us | 0.056 us | 149 | | ChaCha20-BLAKE3.Decrypt | 39.58 us | 0.035 us | 0.033 us | 150 | | XChaCha20-BLAKE3.Encrypt | 40.53 us | 0.038 us | 0.032 us | 151 | | XChaCha20-BLAKE3.Decrypt | 39.50 us | 0.048 us | 0.045 us | 152 | | XChaCha20-BLAKE3-SIV.Encrypt | 36.02 us | 0.673 us | 0.661 us | 153 | | XChaCha20-BLAKE3-SIV.Decrypt | 36.91 us | 0.034 us | 0.032 us | 154 | | ChaCha20-Poly1305.Encrypt | 32.87 us | 0.051 us | 0.043 us | 155 | | ChaCha20-Poly1305.Decrypt | 32.92 us | 0.187 us | 0.175 us | 156 | | XChaCha20-Poly1305.Encrypt | 32.85 us | 0.046 us | 0.039 us | 157 | | XChaCha20-Poly1305.Decrypt | 33.03 us | 0.093 us | 0.087 us | 158 | 159 | #### 64 KiB 160 | | Method | Mean | Error | StdDev | 161 | |:--------------------------:|:--------:|:--------:|:--------:| 162 | | ChaCha20-BLAKE3.Encrypt | 63.93 us | 0.098 us | 0.091 us | 163 | | ChaCha20-BLAKE3.Decrypt | 62.47 us | 0.142 us | 0.133 us | 164 | | XChaCha20-BLAKE3.Encrypt | 64.31 us | 0.141 us | 0.131 us | 165 | | XChaCha20-BLAKE3.Decrypt | 62.67 us | 0.084 us | 0.078 us | 166 | | XChaCha20-BLAKE3-SIV.Encrypt | 59.08 us | 0.053 us | 0.049 us | 167 | | XChaCha20-BLAKE3-SIV.Decrypt | 60.09 us | 0.052 us | 0.049 us | 168 | | ChaCha20-Poly1305.Encrypt | 65.33 us | 0.182 us | 0.142 us | 169 | | ChaCha20-Poly1305.Decrypt | 65.75 us | 0.529 us | 0.494 us | 170 | | XChaCha20-Poly1305.Encrypt | 65.43 us | 0.236 us | 0.197 us | 171 | | XChaCha20-Poly1305.Decrypt | 65.79 us | 0.584 us | 0.546 us | 172 | 173 | #### 128 KiB 174 | | Method | Mean | Error | StdDev | 175 | |:--------------------------:|:--------:|:--------:|:--------:| 176 | | ChaCha20-BLAKE3.Encrypt | 208.2 us | 2.65 us | 2.48 us | 177 | | ChaCha20-BLAKE3.Decrypt | 196.0 us | 2.56 us | 2.39 us | 178 | | XChaCha20-BLAKE3.Encrypt | 208.1 us | 2.94 us | 2.60 us | 179 | | XChaCha20-BLAKE3.Decrypt | 197.1 us | 2.65 us | 2.35 us | 180 | | XChaCha20-BLAKE3-SIV.Encrypt | 206.1 us | 2.82 us | 2.64 us | 181 | | XChaCha20-BLAKE3-SIV.Decrypt | 196.4 us | 3.14 us | 2.93 us | 182 | | ChaCha20-Poly1305.Encrypt | 182.0 us | 1.15 us | 1.08 us | 183 | | ChaCha20-Poly1305.Decrypt | 180.9 us | 1.49 us | 1.39 us | 184 | | XChaCha20-Poly1305.Encrypt | 180.9 us | 1.13 us | 1.00 us | 185 | | XChaCha20-Poly1305.Decrypt | 181.1 us | 1.45 us | 1.29 us | 186 | 187 | #### 32 MiB 188 | | Method | Mean | Error | StdDev | 189 | |:--------------------------:|:--------:|:--------:|:--------:| 190 | | ChaCha20-BLAKE3.Encrypt | 44.08 ms | 0.814 ms | 0.937 ms | 191 | | ChaCha20-BLAKE3.Decrypt | 42.88 ms | 0.736 ms | 0.653 ms | 192 | | XChaCha20-BLAKE3.Encrypt | 41.90 ms | 0.812 ms | 0.967 ms | 193 | | XChaCha20-BLAKE3.Decrypt | 42.31 ms | 0.653 ms | 0.579 ms | 194 | | XChaCha20-BLAKE3-SIV.Encrypt | 42.35 ms | 0.821 ms | 1.008 ms | 195 | | XChaCha20-BLAKE3-SIV.Decrypt | 42.39 ms | 0.694 ms | 0.649 ms | 196 | | ChaCha20-Poly1305.Encrypt | 49.07 ms | 0.289 ms | 0.271 ms | 197 | | ChaCha20-Poly1305.Decrypt | 48.68 ms | 0.171 ms | 0.143 ms | 198 | | XChaCha20-Poly1305.Encrypt | 49.02 ms | 0.150 ms | 0.140 ms | 199 | | XChaCha20-Poly1305.Decrypt | 48.77 ms | 0.195 ms | 0.173 ms | 200 | --------------------------------------------------------------------------------