Commit graph

716 commits

Author SHA1 Message Date
Frank Denis
4b593a6c24
std.crypto: improve KT documentation, use key_length for B3 key length (#25807)
It was not obvious that the KT128/KT256 customization string can be
used to set a key, or what it was designed to be used for at all.

Also properly use key_length and not digest_length for the BLAKE3
key length (no practical changes as they are both 32, but that was
confusing).

Remove unneeded simd_degree copies by the way, and that doesn't need
to be in the public interface.
2025-11-07 08:20:04 +01:00
Frank Denis
ee4df4ad3e
crypto - threaded K12: separate context computation from thread spawning (#25793)
* threaded K12: separate context computation from thread spawning

Compute all contexts and store them in a pre-allocated array,
then spawn threads using the pre-computed contexts.

This ensures each context is fully materialized in memory with the
correct values before any thread tries to access it.

* kt128: unroll the permutation rounds only twice

This appears to deliver the best performance thanks to improved cache
utilization, and it’s consistent with what we already do for SHA3.
2025-11-03 17:09:00 +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
Andrew Kelley
d257b1337a std.Io.Threaded: fix compilation failures on Windows 2025-10-29 06:20:50 -07:00
Andrew Kelley
031044b399 std: fix macos compilation errors 2025-10-29 06:20:49 -07:00
Andrew Kelley
63801c4b05 std.crypto.Certificate.Bundle: remove use of File.readAll 2025-10-29 06:20:49 -07:00
Andrew Kelley
47aa5a70a5 std: updating to std.Io interface
got the build runner compiling
2025-10-29 06:20:48 -07:00
Alex Rønne Petersen
dba1bf9353 remove all Oracle Solaris support
There is no straightforward way for the Zig team to access the Solaris system
headers; to do this, one has to create an Oracle account, accept their EULA to
download the installer ISO, and finally install it on a machine or VM. We do not
have to jump through hoops like this for any other OS that we support, and no
one on the team has expressed willingness to do it.

As a result, we cannot audit any Solaris contributions to std.c or other
similarly sensitive parts of the standard library. The best we would be able to
do is assume that Solaris and illumos are 100% compatible with no way to verify
that assumption. But at that point, the solaris and illumos OS tags would be
functionally identical anyway.

For Solaris especially, any contributions that involve APIs introduced after the
OS was made closed-source would also be inherently more risky than equivalent
contributions for other proprietary OSs due to the case of Google LLC v. Oracle
America, Inc., wherein Oracle clearly demonstrated its willingness to pursue
legal action against entities that merely copy API declarations.

Finally, Oracle laid off most of the Solaris team in 2017; the OS has been in
maintenance mode since, presumably to be retired completely sometime in the 2030s.

For these reasons, this commit removes all Oracle Solaris support.

Anyone who still wishes to use Zig on Solaris can try their luck by simply using
illumos instead of solaris in target triples - chances are it'll work. But there
will be no effort from the Zig team to support this use case; we recommend that
people move to illumos instead.
2025-10-27 07:35:38 -07:00
Matthew Lugg
1881ee4587
std: split up ecdsa tests 2025-10-18 09:28:43 +01:00
Frank Denis
e77a7c5c45
crypto.ecdsa: trim the number of tests we perform
The Wycheproof test suite is extensive, but takes a long time to
complete on CI.

Keep only the most relevant ones and take it as an opportunity to describe
what they are.

The remaining ones are still available for manual testing when required.
2025-10-18 09:28:43 +01:00
mlugg
7a5d2a196f
tweak tests to avoid timeouts 2025-10-18 09:28:42 +01:00
Frank Denis
6669885aa2
Faster BLAKE3 implementation (#25574)
This is a rewrite of the BLAKE3 implementation, with vectorization.

On Apple Silicon, the new implementation is about twice as fast as the previous one.

With AVX2, it is more than 4 times faster.

With AVX512, it is more than 7.5x faster than the previous implementation (from 678 MB/s to 5086 MB/s).
2025-10-15 14:03:56 +02:00
aarvay
2f3234c76a
std.crypto: add AES-CCM and CBC-MAC (#25526)
* std.crypto: add AES-CCM and CBC-MAC

Add AES-CCM (Counter with CBC-MAC) authenticated encryption and
CBC-MAC message authentication code implementations to the standard
library.

AES-CCM combines CTR mode encryption with CBC-MAC authentication as
specified in NIST SP 800-38C and RFC 3610. It provides authenticated
encryption with support for additional authenticated data (AAD).

CBC-MAC is a simple MAC construction used internally by CCM, specified
in FIPS 113 and ISO/IEC 9797-1.

Includes comprehensive test vectors from RFC 3610 and NIST SP 800-38C.

* std.crypto: add CCM* (encryption-only) support to AES-CCM

Implements CCM* mode per IEEE 802.15.4 specification, extending
AES-CCM to support encryption-only mode when tag_len=0. This is
required by protocols like ZigBee, Thread, and WirelessHART.

Changes:
- Allow tag_len=0 for encryption-only mode (no authentication)
- Skip CBC-MAC computation when tag_len=0 in encrypt/decrypt
- Correctly encode M'=0 in B0 block for CCM* mode
- Add Aes128Ccm0 and Aes256Ccm0 convenience instances
- Add IEEE 802.15.4 test vectors and CCM* tests

* std.crypto: add doc comments for AES-CCM variants
2025-10-14 12:00:44 +02:00
marximimus
07b6dbf8ca std.crypto.tls.Client: fix infinite loop in std.Io.Writer.writeAll 2025-10-09 12:34:34 -07:00
David Rubin
e932ab003f
correct ed25519 test case (#25445) 2025-10-04 02:31:02 +00:00
Andrew Kelley
5ec0a7d8a5 coerce vectors to arrays rather than inline for 2025-09-20 18:33:00 -07:00
Andrew Kelley
426af68b7d compiler: require comptime vector indexes 2025-09-20 18:33:00 -07:00
Alex Rønne Petersen
7857bbd116 std.crypto.ascon: disable Ascon-AEAD128 test on RISC-V with V support 2025-09-20 19:05:32 +02:00
Alex Rønne Petersen
97df4ae3ce
Merge pull request #25268 from alexrp/loongarch
Miscellaneous LoongArch work to prepare for CI
2025-09-19 12:09:48 +02:00
andrewkraevskii
de489031d8 Remove usages of deprecatedWriter 2025-09-18 22:39:33 -07:00
Alex Rønne Petersen
c8c3882380
std.crypto.ml_kem: disable some Kyber tests on LoongArch with LSX
LLVM miscompiles these.
2025-09-18 12:42:24 +02:00
Andrew Kelley
b782cdb9b3
Merge pull request #25249 from jedisct1/siv
std.crypto: add AES-SIV and AES-GCM-SIV
2025-09-17 20:05:23 -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
Frank Denis
8e8a143d62
Avoid logic where we return success in case of an error (#25251)
In ed25519.zig, we checked if a test succeeds, in which case we
returned an error. This was confusing, and Andrew pointed out that
Zig weights branches against errors by default.
2025-09-17 12:09:35 +02:00
Frank Denis
b1b2cd7ef8 Parallelize deriveKeys 2025-09-16 23:13:58 +02:00
Frank Denis
5eb7610112 Import crypto/aes_gcm_siv.zig 2025-09-16 23:01:16 +02:00
Frank Denis
dd46e07fb9 std.crypto: add AES-SIV and AES-GCM-SIV
The Zig standard library lacked schemes that resist nonce reuse.

AES-SIV and AES-GCM-SIV are the standard options for this.

AES-GCM-SIV can be very useful when Zig is used to target embedded
systems, and AES-SIV is especially useful for key wrapping.

Also take it as an opportunity to add a bunch of test vectors to
modes.ctr and make sure it works with block ciphers whose size is
not 16.
2025-09-16 12:45:08 +02:00
Frank Denis
1872c85ac2 std.crypto.ed25519: support cofactorless verification
Add verifyStrict() functions for cofactorless verification.

Also:

- Support messages < 64 characters in the test vectors
- Allow mulDoubleBasePublic to return the identity as a regular
value. There are valid use cases for this.
2025-09-08 14:25:57 -07:00
Igor Anić
c41b9d7508
ECDSA signature der encoding should produce smallest number of octets (#25177)
I noticed this by stress testing my tls server implementation. From time to time curl (and other tools: ab, vegeta) will report invalid signature. I trace the problem to the way how std lib is encoding raw signature into der format. Using raw signature I got in some cases different encoding using std and openssl. Std is not producing minimal der when signature `r` or `s` integers has leading zero(es).

Here is an example to illustrate difference. Notice leading 00 in `s`
integer which is removed in openssl encoding but not in std encoding.

```Zig
const std = @import("std");

test "ecdsa signature to der" {
    // raw signature r and s bytes
    const raw = hexToBytes(
        \\ 49  63  0c  94  95  2e  ff  4b  02  bf  35  c4  97  9e  a7  24
        \\ 20  dc  94  de  aa  1b  17  ff  e1  49  25  3e  34  ef  e8  d0
        \\ c4  43  aa  7b  a9  f3  9c  b9  f8  72  7d  d7  0c  9a  13  1e
        \\
        \\ 00  56  85  43  d3  d4  05  62  a1  1d  d8  a1  45  44  b5  dd
        \\ 62  9f  d1  e0  ab  f1  cd  4a  85  d0  1f  5d  11  d9  f8  89
        \\ 89  d4  59  0c  b0  6e  ea  3c  19  6a  f7  0b  1a  4a  ce  f1
    );
    // encoded by openssl
    const expected = hexToBytes(
        \\ 30  63  02  30
        \\ 49  63  0c  94  95  2e  ff  4b  02  bf  35  c4  97  9e  a7  24
        \\ 20  dc  94  de  aa  1b  17  ff  e1  49  25  3e  34  ef  e8  d0
        \\ c4  43  aa  7b  a9  f3  9c  b9  f8  72  7d  d7  0c  9a  13  1e
        \\
        \\ 02  2f
        \\ 56  85  43  d3  d4  05  62  a1  1d  d8  a1  45  44  b5  dd
        \\ 62  9f  d1  e0  ab  f1  cd  4a  85  d0  1f  5d  11  d9  f8  89
        \\ 89  d4  59  0c  b0  6e  ea  3c  19  6a  f7  0b  1a  4a  ce  f1
    );
    // encoded by std
    const actual = hexToBytes(
        \\ 30  64  02  30
        \\ 49  63  0c  94  95  2e  ff  4b  02  bf  35  c4  97  9e  a7  24
        \\ 20  dc  94  de  aa  1b  17  ff  e1  49  25  3e  34  ef  e8  d0
        \\ c4  43  aa  7b  a9  f3  9c  b9  f8  72  7d  d7  0c  9a  13  1e
        \\
        \\ 02  30
        \\ 00  56  85  43  d3  d4  05  62  a1  1d  d8  a1  45  44  b5  dd
        \\ 62  9f  d1  e0  ab  f1  cd  4a  85  d0  1f  5d  11  d9  f8  89
        \\ 89  d4  59  0c  b0  6e  ea  3c  19  6a  f7  0b  1a  4a  ce  f1
    );
    _ = actual;

    const Ecdsa = std.crypto.sign.ecdsa.EcdsaP384Sha384;
    const sig = Ecdsa.Signature.fromBytes(raw);
    var buf: [Ecdsa.Signature.der_encoded_length_max]u8 = undefined;
    const encoded = sig.toDer(&buf);

    try std.testing.expectEqualSlices(u8, &expected, encoded);
}

pub fn hexToBytes(comptime hex: []const u8) [removeNonHex(hex).len / 2]u8 {
    @setEvalBranchQuota(1000 * 100);
    const hex2 = comptime removeNonHex(hex);
    comptime var res: [hex2.len / 2]u8 = undefined;
    _ = comptime std.fmt.hexToBytes(&res, hex2) catch unreachable;
    return res;
}
fn removeNonHex(comptime hex: []const u8) []const u8 {
    @setEvalBranchQuota(1000 * 100);
    var res: [hex.len]u8 = undefined;
    var i: usize = 0;
    for (hex) |c| {
        if (std.ascii.isHex(c)) {
            res[i] = c;
            i += 1;
        }
    }
    return res[0..i];
}
```

Trimming leading zeroes from signature integers fixes encoding.
2025-09-08 22:53:03 +02:00
Andrew Kelley
b7104231af
Merge pull request #25077 from ziglang/GenericReader
std.Io: delete GenericReader, AnyReader, FixedBufferStream; and related API breakage
2025-08-30 12:43:52 -07:00
Alex Rønne Petersen
66b43234bb
std: disable sha3-512 single test on RISC-V with V support
https://github.com/ziglang/zig/issues/25083
2025-08-30 13:27:25 +02:00
Andrew Kelley
07da9567e6 compiler: fix macos build 2025-08-30 00:48:50 -07:00
Andrew Kelley
79f267f6b9 std.Io: delete GenericReader
and delete deprecated alias std.io
2025-08-29 17:14:26 -07:00
Andrew Kelley
888f00e856 std.crypto.ml_kem: update to not use GenericWriter 2025-08-28 18:30:57 -07:00
Andrew Kelley
9860dd475a std: delete most remaining uses of GenericWriter 2025-08-28 18:30:57 -07:00
Andrew Kelley
57dbc9e74a std.Io: delete GenericWriter 2025-08-28 18:30:57 -07:00
Frank Denis
12a58087a4
Fix TLS 1.2 client key exchange to use negotiated named group (#25007)
The TLS 1.2 implementation was incorrectly hardcoded to always send the
secp256r1 public key in the client key exchange message, regardless of
which elliptic curve the server actually negotiated.

This caused TLS handshake failures with servers that preferred other curves
like X25519.

This fix:

- Tracks the negotiated named group from the server key exchange message
- Dynamically selects the correct public key (X25519, secp256r1, or
  secp384r1) based on what the server negotiated
- Properly constructs the client key exchange message with the
  appropriate key size for each curve type

Fixes TLS 1.2 connections to servers like ziglang.freetls.fastly.net
that prefer X25519 over secp256r1.
2025-08-27 11:18:40 +02:00
Erik Schlyter
37f4bee92a
Fix #24999: copy left-overs before we XOR into c. (#25001)
It is important we copy the left-overs in the message *before* we XOR
it into the ciphertext, because if we're encrypting in-place (i.e., m ==
c), we will manipulate the message that will be used for tag generation.
This will generate faulty tags when message length doesn't conform with
16 byte blocks.
2025-08-25 15:59:42 +00:00
Andrew Kelley
a0f9a5e78d std: more reliable HTTP and TLS networking
* std.Io.Reader: fix confused semantics of rebase. Before it was
  ambiguous whether it was supposed to be based on end or seek. Now it
  is clearly based on seek, with an added assertion for clarity.

* std.crypto.tls.Client: fix panic due to not enough buffer size
  available. Also, avoid unnecessary rebasing.

* std.http.Reader: introduce max_head_len to limit HTTP header length.
  This prevents crash in underlying reader which may require a minimum
  buffer length.

* std.http.Client: choose better buffer sizes for streams and TLS
  client. Crucially, the buffer shared by HTTP reader and TLS client
  needs to be big enough for all http headers *and* the max TLS record
  size. Bump HTTP header size default from 4K to 8K.

fixes #24872

I have noticed however that there are still fetch problems
2025-08-16 00:16:15 -07:00
Frank Denis
c1eff72c4a
crypto/aes_ocb.zig: actually check against test vectors (#24835)
And use the correct bit endianness for padding
2025-08-15 13:09:06 +00:00
Frank Denis
96e4825fbb
Validate wildcard TLS certificates correctly (#24829)
Validate wildcard certificates as specified in RFC 6125.

In particular, `*.example.com` should match `foo.example.com` but
NOT `bar.foo.example.com` as it previously did.
2025-08-14 13:57:00 +00:00
Erik Schlyter
7abd62800c std.crypto.aegis: Absorb ad instead of encrypting it.
`Aegis256XGeneric` behaves differently than `Aegis128XGeneric` in that
it currently encrypts associated data instead of just absorbing it. Even
though the end result is the same, there's no point in encrypting and
copying the ad into a buffer that gets overwritten anyway. This fix
makes `Aegis256XGeneric` behave the same as `Aegis128XGeneric`.
2025-08-13 09:00:57 +02:00
Andrew Kelley
749f10af49 std.ArrayList: make unmanaged the default 2025-08-11 15:52:49 -07:00
Andrew Kelley
1ba6838bc3
Merge pull request #24740 from ziglang/http-plus-fixes
fetch, tls, and http fixes
2025-08-08 12:33:53 -07:00
Andrew Kelley
94dd28b7f7 std.Io: delete CountingWriter 2025-08-07 22:26:42 -07:00
Andrew Kelley
8721efece4 std.crypto.tls.Client: always write to buffer
simplifies the logic & makes it respect limit
2025-08-07 19:55:40 -07:00
Andrew Kelley
46b34949c3 TLS, HTTP, and package fetching fixes
* TLS: add missing assert for output buffer length requirement
* TLS: add missing flushes
* TLS: add flush implementation
* TLS: finish drain implementation
* HTTP: correct buffer sizes for TLS
* HTTP: expose a getReadError method on Connection
* HTTP: add missing flush on sendBodyComplete
* Fetch: remove unwanted deinit
* Fetch: improve error reporting
2025-08-07 10:04:52 -07:00
Andrew Kelley
3837862e52 fix 32-bit builds 2025-08-07 10:04:52 -07:00