Commit graph

89 commits

Author SHA1 Message Date
Adrià Arrufat
02c5f05e2f std: replace usages of std.mem.indexOf with std.mem.find 2025-12-05 14:31:27 +01:00
Frank Denis
6fe95c28cf Argon2: use the std.Io interface
Also reduce the memory required by tests.

4GB for every test is way too much and doesn't provide much benefits
in testing the algorithms.
2025-12-02 23:03:52 +01:00
Frank Denis
9ede8ee135 Add std.crypto.hash.sha3.{KT128,KT256} - RFC 9861. (#25593)
KangarooTwelve is a family of two fast and secure extendable-output
functions (XOFs): KT128 and KT256. These functions generalize
traditional hash functions by allowing arbitrary output lengths.

KangarooTwelve was designed by SHA-3 authors. It aims to deliver
higher performance than the SHA-3 and SHAKE functions defined in
FIPS 202, while preserving their flexibility and core security
principles.

On high-end platforms, it can take advantage of parallelism,
whether through multiple CPU cores or SIMD instructions.

As modern SHA-3 constructions, KT128 and KT256 can serve as
general-purpose hash functions and can be used, for example, in
key-derivation, and with arbitrarily large inputs.

RFC9861: https://datatracker.ietf.org/doc/rfc9861/
2025-11-26 10:08:09 +01:00
Andrew Kelley
bb3b5d09cc Revert std.crypto kangarootwelve addition
I would like a chance to review this before it lands, please. Feel free
to submit the work again without changes and I will make review
comments.

In the meantime, these reverts avoid intermittent CI failures, and
remove bad patterns from occurring in the standard library that other
users might copy.

Revert "std.crypto: improve KT documentation, use key_length for B3 key length (#25807)"

This reverts commit 4b593a6c24.

Revert "crypto - threaded K12: separate context computation from thread spawning (#25793)"

This reverts commit ee4df4ad3e.

Revert "crypto.kt128: when using incremental hashing, use SIMD when possible (#25783)"

This reverts commit bf9082518c.

Revert "Add std.crypto.hash.sha3.{KT128,KT256} - RFC 9861. (#25593)"

This reverts commit 95c76b1b4a.
2025-11-21 19:43:01 -08:00
Frank Denis
ce355e0ba5
Add ML-DSA post-quantum signatures (#25862)
ML-DSA is a post-quantum signature scheme that was recently
standardized by NIST.

Keys and signatures are pretty large, not making it a drop-in
replacement for classical signature schemes.

But if you are shipping keys that may still be used in 10 years
or whenever large quantum computers able to break ECC arrive,
it that ever happens, and you don't have the ability to replace
these keys, ML-DSA is for you.

Performance is great, verification is faster than Ed25519 / ECDSA.

I tried manual vectorization, but it wasn't worth it, the compiler
does at good job at auto-vectorization already.
2025-11-10 14:11:30 +01:00
Frank Denis
bf9082518c
crypto.kt128: when using incremental hashing, use SIMD when possible (#25783)
Also add plain kt128 (without threading) to the benchmarks
2025-11-02 11:31:00 +01:00
Frank Denis
95c76b1b4a
Add std.crypto.hash.sha3.{KT128,KT256} - RFC 9861. (#25593)
KT128 and KT256 are fast, secure cryptographic hash functions based on Keccak (SHA-3).

They can be seen as the modern version of SHA-3, and evolution of SHAKE, with better performance.

After the SHA-3 competition, the Keccak team proposed these variants in 2016, and the constructions underwent 8 years of public scrutiny before being standardized in October 2025 as RFC 9861.

They uses a tree-hashing mode on top of TurboSHAKE, providing both high security and excellent performance, especially on large inputs.

They support arbitrary-length output and optional customization strings.

Hashing of very large inputs can be done using multiple threads, for high throughput.

KT128 provides 128-bit security strength, equivalent to AES-128 and SHAKE128, which is sufficient for virtually all applications.

KT256 provides 256-bit security strength, equivalent to SHA-512. For virtually all applications, KT128 is enough (equivalent to SHA-256 or BLAKE3).

For small inputs, TurboSHAKE128 and TurboSHAKE256 (which KT128 and KT256 are based on) can be used instead as they have less overhead.
2025-11-01 14:03:43 +00:00
Frank Denis
d5585bc650
Implement threaded BLAKE3 (#25587)
Allows BLAKE3 to be computed using multiple threads.
2025-11-01 07:40:03 +01:00
andrewkraevskii
de489031d8 Remove usages of deprecatedWriter 2025-09-18 22:39:33 -07:00
Frank Denis
4406127cca
std.crypto: add Ascon-AEAD, Ascon-Hash, Ascon-CHash (#25239)
Ascon is the family of cryptographic constructions standardized by NIST
for lightweight cryptography.

The Zig standard library already included the Ascon permutation itself,
but higher-level constructions built on top of it were intentionally
postponed until NIST released the final specification.

That specification has now been published as NIST SP 800-232:
https://csrc.nist.gov/pubs/sp/800/232/final

With this publication, we can now confidently include these constructions
in the standard library.
2025-09-17 19:59:55 -07:00
Andrew Kelley
0e37ff0d59 std.fmt: breaking API changes
added adapter to AnyWriter and GenericWriter to help bridge the gap
between old and new API

make std.testing.expectFmt work at compile-time

std.fmt no longer has a dependency on std.unicode. Formatted printing
was never properly unicode-aware. Now it no longer pretends to be.

Breakage/deprecations:
* std.fs.File.reader -> std.fs.File.deprecatedReader
* std.fs.File.writer -> std.fs.File.deprecatedWriter
* std.io.GenericReader -> std.io.Reader
* std.io.GenericWriter -> std.io.Writer
* std.io.AnyReader -> std.io.Reader
* std.io.AnyWriter -> std.io.Writer
* std.fmt.format -> std.fmt.deprecatedFormat
* std.fmt.fmtSliceEscapeLower -> std.ascii.hexEscape
* std.fmt.fmtSliceEscapeUpper -> std.ascii.hexEscape
* std.fmt.fmtSliceHexLower -> {x}
* std.fmt.fmtSliceHexUpper -> {X}
* std.fmt.fmtIntSizeDec -> {B}
* std.fmt.fmtIntSizeBin -> {Bi}
* std.fmt.fmtDuration -> {D}
* std.fmt.fmtDurationSigned -> {D}
* {} -> {f} when there is a format method
* format method signature
  - anytype -> *std.io.Writer
  - inferred error set -> error{WriteFailed}
  - options -> (deleted)
* std.fmt.Formatted
  - now takes context type explicitly
  - no fmt string
2025-07-07 22:43:51 -07:00
Andrew Kelley
0b3f0124dc std.io: move getStdIn, getStdOut, getStdErr functions to fs.File
preparing to rearrange std.io namespace into an interface

how to upgrade:

std.io.getStdIn() -> std.fs.File.stdin()
std.io.getStdOut() -> std.fs.File.stdout()
std.io.getStdErr() -> std.fs.File.stderr()
2025-07-07 22:43:51 -07:00
Frank Denis
8d824dfdd0
crypto.pwhash.bcrypt: make silently_truncate_password a member of Params (#22792)
* bcrypt: make silently_truncate_password a member of Params

This removes the need for having both `bcrypt()` and
`bcryptWithTruncation()` in the public API.

And whether truncation happens or not becomes even more explicit.

* Update crypto benchmark
2025-02-19 22:37:51 +01:00
Frank Denis
295c5a64f5
Reinstantiates AEGIS-MAC with the final construction (#22205)
This reverts commit c9d6f8b505.
2024-12-11 18:52:43 +01:00
Frank Denis
c9d6f8b505
Remove parallel variants of AEGIS-MAC (#22146)
The construction is likely to change before standardization
2024-12-04 22:45:07 +00:00
Frank Denis
636308a17d
std.crypto.aes: introduce AES block vectors (#22023)
* std.crypto.aes: introduce AES block vectors

Modern Intel CPUs with the VAES extension can handle more than a
single AES block per instruction.

So can some ARM and RISC-V CPUs. Software implementations with
bitslicing can also greatly benefit from this.

Implement low-level operations on AES block vectors, and the
parallel AEGIS variants on top of them.

AMD Zen4:

      aegis-128x4:      73225 MiB/s
      aegis-128x2:      51571 MiB/s
       aegis-128l:      25806 MiB/s
      aegis-256x4:      46742 MiB/s
      aegis-256x2:      30227 MiB/s
        aegis-256:       8436 MiB/s
       aes128-gcm:       5926 MiB/s
       aes256-gcm:       5085 MiB/s

AES-GCM, and anything based on AES-CTR are also going to benefit
from this later.

* Make AEGIS-MAC twice a fast
2024-11-22 10:00:49 +01:00
Frank Denis
8a00bd4ce6
std.crypto: make the key pair API creation consistent (#21955)
Our key pair creation API was ugly and inconsistent between ecdsa
keys and other keys.

The same `generate()` function can now be used to generate key pairs,
and that function cannot fail.

For deterministic keys, a `generateDeterministic()` function is
available for all key types.

Fix comments and compilation of the benchmark by the way.

Fixes #21002
2024-11-19 18:05:09 +01:00
Frank Denis
e45bdc6bd6
std.crypto.pcurves.*: simpler, smaller, faster u64 addition with carry (#19644)
signature/s:

Algorithm        Before     After
---------------+---------+-------
ecdsa-p256        3707       4396
ecdsa-p384        1067       1332
ecdsa-secp256k1   4490       5147

Add ECDSA to the benchmark by the way.
2024-04-14 01:13:22 +02:00
regeliv
13a9d94a80 Change std.os.exit to std.process.exit 2024-03-22 15:01:02 +02:00
e4m2
8d56e472c9 Replace std.rand references with std.Random 2024-02-08 15:21:35 +01:00
mlugg
f26dda2117 all: migrate code to new cast builtin syntax
Most of this migration was performed automatically with `zig fmt`. There
were a few exceptions which I had to manually fix:

* `@alignCast` and `@addrSpaceCast` cannot be automatically rewritten
* `@truncate`'s fixup is incorrect for vectors
* Test cases are not formatted, and their error locations change
2023-06-24 16:56:39 -07:00
Eric Joldasov
50339f595a all: zig fmt and rename "@XToY" to "@YFromX"
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>
2023-06-19 12:34:42 -07:00
Frank Denis
879f0b9cee
Fix std.hash benchmarks (#15917) 2023-06-02 20:08:28 +02:00
Andrew Kelley
6261c13731 update codebase to use @memset and @memcpy 2023-04-28 13:24:43 -07:00
Frank Denis
dff4bbfd24
Remove Gimli and Xoodoo from the standard library (#14928)
These are great permutations, and there's nothing wrong with them
from a practical security perspective.

However, both were competing in the NIST lightweight crypto
competition.

Gimli didn't pass the 3rd selection round, and is not much used
in the wild besides Zig and libhydrogen. It will never be
standardized and is unlikely to get more traction in the future.

Xoodyak, that Xoodoo is the permutation of, was a finalist.

It has a lot of advantages and *might* be standardized without NIST.
But this is too early to tell, and too risky to commit to it
in a standard library.

For lightweight crypto, Ascon is the one that we know NIST will
standardize and that we can safely rely on from a usage perspective.

Switch to a traditional ChaCha-based CSPRNG, with an Ascon-based one
as an option for constrained systems.

Add a RNG benchmark by the way.

Gimli and Xoodoo served us well. Their code will be maintained,
but outside the standard library.
2023-03-21 04:54:10 +00:00
Bas Westerbaan
4414f9c46e
Add Kyber post-quantum key encapsulation mechanism (#14902)
Implementation of the IND-CCA2 post-quantum secure key encapsulation
mechanism (KEM) CRYSTALS-Kyber, as submitted to the third round of the NIST
Post-Quantum Cryptography (v3.02/"draft00"), and selected for standardisation.

Co-authored-by: Frank Denis <124872+jedisct1@users.noreply.github.com>
2023-03-15 03:50:45 +00:00
Frank Denis
36d47dd199
std.crypto.hash.sha3: add TurboSHAKE (#14824) 2023-03-07 10:04:45 +01:00
Frank Denis
28364166e8
crypto.hash.sha3: make permutation generic and public, add SHAKE (#14756)
Make the Keccak permutation public, as it's useful for more than
SHA-3 (kMAC, SHAKE, TurboSHAKE, TupleHash, etc).

Our Keccak implementation was accepting f as a comptime parameter,
but always used 64-bit words and 200 byte states, so it actually
didn't work with anything besides f=1600.

That has been fixed. The ability to use reduced-round versions
was also added in order to support M14 and K12.

The state was constantly converted back and forth between bytes
and words, even though only a part of the state is actually used
for absorbing and squeezing bytes. It was changed to something
similar to the other permutations we have, so we can avoid extra
copies, and eventually add vectorized implementations.

In addition, the SHAKE extendable output function (XOF) was
added (SHAKE128, SHAKE256). It is required by newer schemes,
such as the Kyber post-quantum key exchange mechanism, whose
implementation is currently blocked by SHAKE missing from our
standard library.

Breaking change: `Keccak_256` and `Keccak_512` were renamed to
`Keccak256` and `Keccak512` for consistency with all other
hash functions.
2023-03-02 06:13:40 +00:00
Frank Denis
c7f479c3cb
crypto/benchmark.zig: fix pointer capture of non pointer type (#14722) 2023-02-24 19:45:24 +00:00
Chris Boesch
438b71155a
crypto: add AES-CMAC (RFC 4493) (#14545)
* crypto: add AES-CMAC

Co-authored-by: Frank Denis <124872+jedisct1@users.noreply.github.com>
2023-02-16 21:18:20 +01:00
Frank Denis
4be1bb4aac
std.crypto benchmark: don't use a relative path to import std (#13772) 2022-12-05 04:44:14 +00:00
Frank Denis
ea05223b63
std.crypto.auth: add AEGIS MAC (#13607)
* Update the AEGIS specification URL to the current draft

* std.crypto.auth: add AEGIS MAC

The Pelican-based authentication function of the AEGIS construction
can be used independently from authenticated encryption, as a faster
and more secure alternative to GHASH/POLYVAL/Poly1305.

We already expose GHASH, POLYVAL and Poly1305 for use outside AES-GCM
and ChaChaPoly, so there are no reasons not to expose the MAC from AEGIS
as well.

Like other 128-bit hash functions, finding a collision only requires
~2^64 attempts or inputs, which may still be acceptable for many
practical applications.

Benchmark (Apple M1):

    siphash128-1-3:       3222 MiB/s
             ghash:       8682 MiB/s
    aegis-128l mac:      12544 MiB/s

Benchmark (Zen 2):

    siphash128-1-3:       4732 MiB/s
             ghash:       5563 MiB/s
    aegis-128l mac:      19270 MiB/s
2022-11-22 18:16:04 +01:00
Frank Denis
c45c6cd492 Add the POLYVAL universal hash function
POLYVAL is GHASH's little brother, required by the AES-GCM-SIV
construction. It's defined in RFC8452.

The irreducible polynomial is a mirror of GHASH's (which doesn't
change anything in our implementation that didn't reverse the raw
bits to start with).

But most importantly, POLYVAL encodes byte strings as little-endian
instead of big-endian, which makes it a little bit faster on the
vast majority of modern CPUs.

So, both share the same code, just with comptime magic to use the
correct endianness and only double the key for GHASH.
2022-11-20 18:13:19 -05:00
Frank Denis
9c0d975a09
Revamp the ed25519 API (#13309) 2022-10-27 19:07:42 +02:00
Matheus C. França
b41b35f578
crypto/benchmark - replace testing allocator
Fix error: Cannot use testing allocator outside of test block
2022-10-20 14:04:59 +03:00
jagt
76311aebff std: fix crypto and hash benchmark 2022-04-24 23:01:06 -04:00
Andrew Kelley
449554a730 stage2: remove anytype fields from the language
closes #10705
2022-02-01 19:06:40 -07:00
Lee Cannon
1093b09a98
allocgate: renamed getAllocator function to allocator 2021-11-30 23:32:47 +00:00
Lee Cannon
85de022c56
allocgate: std Allocator interface refactor 2021-11-30 23:32:47 +00:00
Andrew Kelley
902df103c6 std lib API deprecations for the upcoming 0.9.0 release
See #3811
2021-11-30 00:13:07 -07:00
lucky
c61fbe77c8
add argon2 kdf (#9756) 2021-11-15 04:47:57 +01:00
Ominitay
c1a5ff34f3 std.rand: Refactor Random interface
These changes have been made to resolve issue #10037. The `Random`
interface was implemented in such a way that causes significant slowdown
when calling the `fill` function of the rng used.

The `Random` interface is no longer stored in a field of the rng, and is
instead returned by the child function `random()` of the rng. This
avoids the performance issues caused by the interface.
2021-10-27 16:07:48 -04:00
Andrew Kelley
6115cf2240 migrate from std.Target.current to @import("builtin").target
closes #9388
closes #9321
2021-10-04 23:48:55 -07:00
Ali Chraghi
db181b173f
Update hash & crypto benchmarks run comment (#9790)
* sync function arguments name with other same functions
2021-09-19 23:03:18 -07:00
lucky
f011f13933
fix missing paths (#9754)
increase bcrypt benchmark rounds

Co-authored-by: lucky <>
2021-09-13 17:31:17 +02:00
Andrew Kelley
d29871977f remove redundant license headers from zig standard library
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-24 12:25:09 -07:00
lucky
8c41a8e761
add scrypt kdf (#9577)
add phc encoding parser
add password hash functions to benchmark
change bcrypt to be consistent with scrypt

Co-authored-by: lucky <>
2021-08-24 13:58:09 +02:00
Andrew Kelley
193c529b8c CLI: rename --override-lib-dir to --zig-lib-dir
This breaking change disambiguates between overriding the lib dir when
performing an installation with the Zig Build System, and overriding the
lib dir that the Zig installation itself uses.
2021-06-14 11:33:27 -07:00
Frank Denis
119fc318a7 std/crypto/chacha20: add round-reduced versions & cleanup internals
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-17 11:25:51 -07:00
Frank Denis
a5a3ad4f95 std/crypto: add AES-OCB
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-02-28 20:40:49 -08:00