aboutsummaryrefslogtreecommitdiff
path: root/lib/std/crypto.zig
AgeCommit message (Collapse)Author
2022-07-01crypto: add the Xoodoo permutation, prepare for Gimli deprecation (#11866)Frank Denis
Gimli was a game changer. A permutation that is large enough to be used in sponge-like constructions, yet small enough to be compact to implement and fast on a wide range of platforms. And Gimli being part of the Zig standard library was awesome. But since then, Gimli entered the NIST Lightweight Cryptography Competition, competing againt other candidates sharing a similar set of properties. Unfortunately, Gimli didn't pass the 3rd round. There are no practical attacks against Gimli when used correctly, but NIST's decision means that Gimli is unlikely to ever get any traction. So, maybe the time has come to move Gimli from the standard library to another repository. We shouldn't do it without providing an alternative, though. And the best candidate for this is probably Xoodoo. Xoodoo is the core function of Xoodyak, one of the finalists of the NIST LWC competition, and the most direct competitor to Gimli. It is also a 384-bit permutation, so it can easily be used everywhere Gimli was used with no parameter changes. It is the building block of Xoodyak (for actual encryption and hashing) as well as Charm, that some Zig applications are already using. Like Gimli that it was heavily inspired from, it is compact and suitable for constrained environments. This change adds the Xoodoo permutation to std.crypto.core. The set of public functions includes everything required to later implement existing Xoodoo-based constructions. In order to prepare for the Gimli deprecation, the default CSPRNG was changed to a Xoodoo-based that works exactly the same way.
2022-07-01std.crypto.hash: allow creating hash functions from compositions (#11965)Frank Denis
A hash function cascade was a common way to avoid length-extension attacks with traditional hash functions such as the SHA-2 family. Add `std.crypto.hash.composition` to do exactly that using arbitrary hash functions, and pre-define the common SHA2-based ones. With this, we can now sign and verify Bitcoin signatures in pure Zig.
2022-06-29std.crypto.ecc: add support for the secp256k1 curve (#11880)Frank Denis
std.crypto.ecc: add support for the secp256k1 curve Usage of the secp256k1 elliptic curve recently grew exponentially, since this is the curve used by Bitcoin and other popular blockchains such as Ethereum. With this, Zig has support for all the widely deployed elliptic curves today.
2022-06-15std/crypto: add support for ECDSA signatures (#11855)Frank Denis
ECDSA is the most commonly used signature scheme today, mainly for historical and conformance reasons. It is a necessary evil for many standard protocols such as TLS and JWT. It is tricky to implement securely and has been the root cause of multiple security disasters, from the Playstation 3 hack to multiple critical issues in OpenSSL and Java. This implementation combines lessons learned from the past with recent recommendations. In Zig, the NIST curves that ECDSA is almost always instantied with use formally verified field arithmetic, giving us peace of mind even on edge cases. And the API rejects neutral elements where it matters, and unconditionally checks for non-canonical encoding for scalars and group elements. This automatically eliminates common vulnerabilities such as https://sk.tl/2LpS695v . ECDSA's security heavily relies on the security of the random number generator, which is a concern in some environments. This implementation mitigates this by computing deterministic nonces using the conservative scheme from Pornin et al. with the optional addition of randomness as proposed in Ericsson's "Deterministic ECDSA and EdDSA Signatures with Additional Randomness" document. This approach mitigates both the implications of a weak RNG and the practical implications of fault attacks. Project Wycheproof is a Google project to test crypto libraries against known attacks by triggering edge cases. It discovered vulnerabilities in virtually all major ECDSA implementations. The entire set of ECDSA-P256-SHA256 test vectors from Project Wycheproof is included here. Zero defects were found in this implementation. The public API differs from the Ed25519 one. Instead of raw byte strings for keys and signatures, we introduce Signature, PublicKey and SecretKey structures. The reason is that a raw byte representation would not be optimal. There are multiple standard representations for keys and signatures, and decoding/encoding them may not be cheap (field elements have to be converted from/to the montgomery domain). So, the intent is to eventually move ed25519 to the same API, which is not going to introduce any performance regression, but will bring us a consistent API, that we can also reuse for RSA.
2022-05-31crypto: add support for the NIST P-384 curve (#11735)Frank Denis
After P-256, here comes P-384, also known as secp384r1. Like P-256, it is required for TLS, and is the current NIST recommendation for key exchange and signatures, for better or for worse. Like P-256, all the finite field arithmetic has been computed and verified to be correct by fiat-crypto.
2022-01-31a small crusade against std.meta.declarationsAndrew Kelley
2022-01-25std.crypto.random: `Random`s are no longer passed by referenceMeghan
2021-11-15add argon2 kdf (#9756)lucky
2021-10-04migrate from `std.Target.current` to `@import("builtin").target`Andrew Kelley
closes #9388 closes #9321
2021-09-09reexport crypto/phc_encoding (#9712)lucky
Co-authored-by: lucky <>
2021-08-24remove redundant license headers from zig standard libraryAndrew Kelley
We already have a LICENSE file that covers the Zig Standard Library. We no longer need to remind everyone that the license is MIT in every single file. Previously this was introduced to clarify the situation for a fork of Zig that made Zig's LICENSE file harder to find, and replaced it with their own license that required annual payments to their company. However that fork now appears to be dead. So there is no need to reinforce the copyright notice in every single file.
2021-08-24add scrypt kdf (#9577)lucky
add phc encoding parser add password hash functions to benchmark change bcrypt to be consistent with scrypt Co-authored-by: lucky <>
2021-05-08std: update usage of std.testingVeikka Tuominen
2021-05-01std.crypto: add support for the NIST P-256 curve (#8627)Frank Denis
Uses verified code generated by fiat-crypto for field arithmetic, and complete formulas to avoid side channels. There's still plenty of room for optimizations, especially with a fixed base. But this gives us a framework to easily add other similar curves.
2021-04-20std/crypto: use finer-grained error sets in function signatures (#8558)Frank Denis
std/crypto: use finer-grained error sets in function signatures Returning the `crypto.Error` error set for all crypto operations was very convenient to ensure that errors were used consistently, and to avoid having multiple error names for the same thing. The flipside is that callers were forced to always handle all possible errors, even those that could never be returned by a function. This PR makes all functions return union sets of the actual errors they can return. The error sets themselves are all limited to a single error. Larger sets are useful for platform-specific APIs, but we don't have any of these in `std/crypto`, and I couldn't find any meaningful way to build larger sets.
2021-03-17std/crypto/chacha20: add round-reduced versions & cleanup internalsFrank Denis
See https://eprint.iacr.org/2019/1492.pdf for justification. 8 rounds ChaCha20 provides a 2.5x speedup, and is still believed to be safe. Round-reduced versions are actually deployed (ex: Android filesystem encryption), and thanks to the magic of comptime, it doesn't take much to support them. This also makes the ChaCha20 code more consistent with the Salsa20 code, removing internal functions that were not part of the public API any more. No breaking changes; the public API remains backwards compatible.
2021-03-14Use a unified error set for std/crypto/*Frank Denis
This ensures that errors are used consistently across all operations.
2021-02-28std/crypto: add AES-OCBFrank Denis
OCB has been around for a long time. It's simpler, faster and more secure than AES-GCM. RFC 7253 was published in 2014. OCB also won the CAESAR competition along with AEGIS. It's been implemented in OpenSSL and other libraries for years. So, why isn't everybody using it instead of GCM? And why don't we have it in Zig already? The sad reason for this was patents. GCM was invented only to work around these patents, and for all this time, OCB was that nice thing that everybody knew existed but that couldn't be freely used. That just changed. The OCB patents are now abandoned, and OCB's author just announced that OCB was officially public domain.
2021-01-04ci: skip crypto tests on windowsAndrew Kelley
Trying to buy us more time on the Windows CI.
2020-12-31Year++Frank Denis
2020-12-18std: introduce a thread-local CSPRNG for general useAndrew Kelley
std.crypto.random * cross platform, even freestanding * can't fail. on initialization for some systems requires calling os.getrandom(), in which case there are rare but theoretically possible errors. The code panics in these cases, however the application may choose to override the default seed function and then handle the failure another way. * thread-safe * supports the full Random interface * cryptographically secure * no syscall required to initialize on Linux (AT_RANDOM) * calls arc4random on systems that support it `std.crypto.randomBytes` is removed in favor of `std.crypto.random.bytes`. I moved some of the Random implementations into their own files in the interest of organization. stage2 no longer requires passing a RNG; instead it uses this API. Closes #6704
2020-11-16std/crypto: add ISAPv2 (ISAP-A-128a) AEADFrank Denis
We currently have ciphers optimized for performance, for compatibility, for size and for specific CPUs. However we lack a class of ciphers that is becoming increasingly important, as Zig is being used for embedded systems, but also as hardware-level side channels keep being found on (Intel) CPUs. Here is ISAPv2, a construction specifically designed for resilience against leakage and fault attacks. ISAPv2 is obviously not optimized for performance, but can be an option for highly sensitive data, when the runtime environment cannot be trusted.
2020-11-07Add mem.timingSafeEql() for constant-time array comparisonFrank Denis
This is a trivial implementation that just does a or[xor] loop. However, this pattern is used by virtually all crypto libraries and in practice, even without assembly barriers, LLVM never turns it into code with conditional jumps, even if one of the parameters is constant. This has been verified to still be the case with LLVM 11.0.0.
2020-11-05std.crypto: namespace constructions a bit moreFrank Denis
With the simple rule that whenever we have or will have 2 similar functions, they should be in their own namespace. Some of these new namespaces currently contain a single function. This is to prepare for reduced-round versions that are likely to be added later.
2020-10-28PascalCase *box names, remove unneeded comptime & parenthesisFrank Denis
Also rename (salsa20|chacha20)Internal() to a better name. And sort reexported crypto.* names
2020-10-25std/crypto: add the bcrypt password hashing functionFrank Denis
The bcrypt function intentionally requires quite a lot of CPU cycles to complete. In addition to that, not having its full state constantly in the CPU L1 cache causes a massive performance drop. These properties slow down brute-force attacks against low-entropy inputs (typically passwords), and GPU-based attacks get little to no advantages over CPUs.
2020-10-25Add (X)Salsa20 and NaCl boxesFrank Denis
The NaCl constructions are available in pretty much all programming languages, making them a solid choice for applications that require interoperability. Go includes them in the standard library, JavaScript has the popular tweetnacl.js module, and reimplementations and ports of TweetNaCl have been made everywhere. Zig has almost everything that NaCl has at this point, the main missing component being the Salsa20 cipher, on top on which NaCl's secretboxes, boxes, and sealedboxes can be implemented. So, here they are! And clean the X25519 API up a little bit by the way.
2020-10-17std/crypto: make the whole APIs more consistentFrank Denis
- use `PascalCase` for all types. So, AES256GCM is now Aes256Gcm. - consistently use `_length` instead of mixing `_size` and `_length` for the constants we expose - Use `minimum_key_length` when it represents an actual minimum length. Otherwise, use `key_length`. - Require output buffers (for ciphertexts, macs, hashes) to be of the right size, not at least of that size in some functions, and the exact size elsewhere. - Use a `_bits` suffix instead of `_length` when a size is represented as a number of bits to avoid confusion. - Functions returning a constant-sized slice are now defined as a slice instead of a pointer + a runtime assertion. This is the case for most hash functions. - Use `camelCase` for all functions instead of `snake_case`. No functional changes, but these are breaking API changes.
2020-10-15std: move std.meta.refAllDecls to std.testingTadeo Kondrak
2020-10-06std/crypto: Add support for AES-GCMFrank Denis
Already pretty fast on platforms with AES-NI, even though GHASH reduction hasn't been optimized yet, and we don't do stitching either.
2020-10-04Merge pull request #6463 from jedisct1/ghashAndrew Kelley
std/crypto: add GHASH implementation
2020-10-01std/crypto: add GHASH implementationFrank Denis
GHASH is required to implement AES-GCM. Optimized implementations for CPUs with instructions for carry-less multiplication will be added next.
2020-09-30Remove unused var, sort std.crypto.*Frank Denis
2020-09-30std/crypto: implement the HKDF constructionFrank Denis
2020-09-29Add AEGIS-256 as wellFrank Denis
2020-09-29std/crypto: add the AEGIS128L AEADFrank Denis
Showcase that Zig can be a great option for high performance cryptography. The AEGIS family of authenticated encryption algorithms was selected for high-performance applications in the final portfolio of the CAESAR competition. They reuse the AES core function, but are substantially faster than the CCM, GCM and OCB modes while offering a high level of security. AEGIS algorithms are especially fast on CPUs with built-in AES support, and the 128L variant fully takes advantage of the pipeline in modern Intel CPUs. Performance of the Zig implementation is on par with libsodium.
2020-09-24Revamp crypto/aesFrank Denis
* Reorganize crypto/aes in order to separate parameters, implementations and modes. * Add a zero-cost abstraction over the internal representation of a block, so that blocks can be kept in vector registers in optimized implementations. * Add architecture-independent aesenc/aesdec/aesenclast/aesdeclast operations, so that any AES-based primitive can be implemented, including these that don't use the original key schedule (AES-PRF, AEGIS, MeowHash...) * Add support for parallelization/wide blocks to take advantage of hardware implementations. * Align T-tables to cache lines in the software implementations to slightly reduce side channels. * Add an optimized implementation for modern Intel CPUs with AES-NI. * Add new tests (AES256 key expansion). * Reimplement the counter mode to work with any block cipher, any endianness and to take advantage of wide blocks. * Add benchmarks for AES.
2020-09-24Move PBKDF2 to a pwhash category, clarify what that category isFrank Denis
Password hashing functions are not general-purpose KDFs, and KDFs don't have to satisfy the same properties as a PHF. This will allow fast KDFs such as the HKDF construction to be in a category of their own, while clarifying what functions are suitable for using passwords as inputs.
2020-09-13fix refRocknest
2020-09-13Reference all crypto declarationsRocknest
2020-09-13Extract kdf.zig to provide namespace documentationRob Napier
2020-09-13Explicitly reference std.crypto.kdf in test caseRob Napier
2020-09-11Add crypto.kdf.pbkdf2Rob Napier
2020-08-22Promote hash/siphash to crypto/siphashFrank Denis
SipHash *is* a cryptographic function, with a 128-bit security level. However, it is not a regular hash function: a secret key is required, and knowledge of that key allows collisions to be quickly computed offline. SipHash is therefore more suitable to be used as a MAC. The same API as other MACs was implemented in addition to functions directly returning an integer. The benchmarks have been updated accordingly. No changes to the SipHash implementation itself.
2020-08-21Hash functions now accept an option setFrank Denis
- This avoids having multiple `init()` functions for every combination of optional parameters - The API is consistent across all hash functions - New options can be added later without breaking existing applications. For example, this is going to come in handy if we implement parallelization for BLAKE2 and BLAKE3. - We don't have a mix of snake_case and camelCase functions any more, at least in the public crypto API Support for BLAKE2 salt and personalization (more commonly called context) parameters have been implemented by the way to illustrate this.
2020-08-20Remove the reset() function from hash functionsFrank Denis
Justification: - reset() is unnecessary; states that have to be reused can be copied - reset() is error-prone. Copying a previous state prevents forgetting struct members. - reset() forces implementation to store sensitive data (key, initial state) in memory even when they are not needed. - reset() is confusing as it has a different meaning elsewhere in Zig.
2020-08-20Breaking: sort std/crypto functions into categoriesFrank Denis
Instead of having all primitives and constructions share the same namespace, they are now organized by category and function family. Types within the same category are expected to share the exact same API.
2020-08-20add license header to all std lib filesAndrew Kelley
add SPDX license identifier copyright ownership is zig contributors
2020-08-17Export crypto.aeadFrank Denis
2020-08-16Rename the field and scalar modulesFrank Denis
Suggested by @kubkon