Geralt is a modern cryptographic library for .NET 6+ based on libsodium and inspired by Monocypher.
  • Simple: an easy-to-learn API with descriptive naming. Only one primitive for each task is provided when possible.
  • Modern: the latest and greatest cryptographic primitives, such as (X)ChaCha20-Poly1305, BLAKE2b, Argon2id, X25519, and Ed25519.
  • Secure: libsodium was audited in 2017 and is the library of choice for lots of projects and even large companies.
  • Fast: libsodium is faster than many other cryptographic libraries. Furthermore, Geralt uses Span<T> buffers to avoid memory allocations.


Geralt is available as a NuGet package. It is supported on the following platforms:
Note that libsodium requires the Visual C++ Redistributable for Visual Studio 2015-2022 on Windows. This dependency is included in the .NET SDK.
If you want your program to be portable (e.g. self-contained), you can keep the relevant vcruntime140.dll file (available on GitHub) in the same directory as your executable.​

Source code

You can find the source code on GitHub.


Geralt is licensed under the MIT license.


  • Span<T> all the things: enables the secure erasure of bytes and boosts performance.
  • Descriptive naming: BLAKE2b, not GenericHash.
  • Same vocabulary for everything: key, nonce, salt, input keying material, output keying material, etc.
  • Minimal parameters: no key parameter for an unkeyed hash.
  • Consistent parameter ordering: buffers come first.
  • Public constants: easy to create buffers.
  • One primitive for each task: (X)ChaCha20-Poly1305, BLAKE2b, Argon2id, X25519, and Ed25519.
  • Some low-level functions: useful for custom constructions.

Out of scope

  • Full misuse resistance (e.g. no nonces or optional nonces). This can limit the user, doesn't work well with spans, and overcomplicates code.
  • Solving the key reuse problem (e.g. a mandatory context for everything or wrappers instead of naked bytes). I'm not convinced either tactic works, and it again adds complexity.
  • Old NaCl APIs, such as crypto_box. These shouldn't be used.
  • Other primitives unless they solve a problem. AES-GCM causes problems (e.g. it requires hardware support).
  • Experimental ideas/custom constructions (e.g. anything without an RFC or Internet Draft), which can go in a separate project.
  • Duplicate methods that return byte arrays.
  • Unnecessary 'convenience' functions, like GenerateKey() in almost every class.
  • Guarded heap allocations, which would add complexity and aren't the fastest.


A big thanks to:
Last modified 7d ago