aboutsummaryrefslogtreecommitdiff
path: root/lib/std/crypto/ecdsa.zig
AgeCommit message (Collapse)Author
2025-10-18std: split up ecdsa testsMatthew Lugg
2025-10-18crypto.ecdsa: trim the number of tests we performFrank Denis
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-09-08ECDSA signature der encoding should produce smallest number of octets (#25177)Igor Anić
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-08-29std.Io: delete GenericReaderAndrew Kelley
and delete deprecated alias std.io
2025-08-05crypto: fix typo in ecdsa commentDavid Rubin
2025-04-20crypto.ecdsa: add the ability to sign/verify prehashed messages (#23607)Frank Denis
2025-04-15crypto.ecdsa: stricter DER decoding of signatures (#23554)Frank Denis
Reject DER-encoded signatures with the top bit set but no leading 0x00 Also add test vectors from Project Wycheproof with ECDSA-P384
2025-03-29crypto.ecdsa: fix EcdsaP384Sha3_384 constant name (#23403)Frank Denis
Spotted by @deatil -- Thanks!
2024-11-19std.crypto: make the key pair API creation consistent (#21955)Frank Denis
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-07std.crypto: delete new functions that are only used onceJacob Young
2024-11-07std.crypto.tls: implement TLSv1.2Jacob Young
2024-08-07std.crypto.ecdsa: use separate function for null seed (#20953)Jakub Dóka
Due to the `std.crypto.ecdsa.KeyPair.create` taking and optional of seed, even if the seed is generated, cross-compiling to the environments without standard random source (eg. wasm) (`std.crypto.random.bytes`) will fail to compile. This commit changes the API of the problematic function and moves the random seed generation to a new utility function.
2024-04-20Rename der_encoded_max_length to der_encoded_length_maxFrank Denis
The `length_min`/`length_max` convention is used everywhere else in `std.crypto.*` so be consistent.
2024-04-09crypto.sha3: implement constructions from NIST SP 800-185 (#19533)Frank Denis
https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-185.pdf This adds useful standard SHA3-based constructions from the NIST SP 800-185 document: - cSHAKE: similar to the SHAKE extensible hash function, but with the addition of a context parameter. - KMAC: SHAKE-based authentication / keyed XOF - TupleHash: unambiguous hashing of tuples These are required by recent protocols and specifications. They also offer properties that none of the currently available constructions in the stdlib offer, especially the ability to safely hash tuples. Other keyed hash functions/XOFs will fall back to using HMAC, which is suboptimal from a performance perspective, but fine from a security perspective.
2024-02-26Remove redundant test name prefixes now that test names are fully qualifiedRyan Liptak
Follow up to #19079, which made test names fully qualified. This fixes tests that now-redundant information in their test names. For example here's a fully qualified test name before the changes in this commit: "priority_queue.test.std.PriorityQueue: shrinkAndFree" and the same test's name after the changes in this commit: "priority_queue.test.shrinkAndFree"
2024-02-12x86_64: implement `@byteSwap` of big integersJacob Young
2023-11-19lib: correct unnecessary uses of 'var'mlugg
2023-11-03x86_64: fix std test failuresJacob Young
2023-10-31std.builtin.Endian: make the tags lower caseAndrew Kelley
Let's take this breaking change opportunity to fix the style of this enum.
2023-10-26x86_64: add missing spillsJacob Young
2023-10-22Revert "Revert "Merge pull request #17637 from jacobly0/x86_64-test-std""Jacob Young
This reverts commit 6f0198cadbe29294f2bf3153a27beebd64377566.
2023-10-22Revert "Merge pull request #17637 from jacobly0/x86_64-test-std"Andrew Kelley
This reverts commit 0c99ba1eab63865592bb084feb271cd4e4b0357e, reversing changes made to 5f92b070bf284f1493b1b5d433dd3adde2f46727. This caused a CI failure when it landed in master branch due to a 128-bit `@byteSwap` in std.mem.
2023-10-21x86_64: disable difficult std tests and hack around more zero-bit typesJacob Young
2023-06-24all: migrate code to new cast builtin syntaxmlugg
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-04-28update codebase to use `@memset` and `@memcpy`Andrew Kelley
2023-04-21cbe: enable CI for std testsJacob Young
2023-04-14secp256k1: Endormorphism.splitScalar() can return an error (#15270)Frank Denis
Fixes #15267
2022-10-28std.sign.ecdsa: add support for incremental signatures (#13332)Frank Denis
Similar to what was done for EdDSA, allow incremental creation and verification of ECDSA signatures. Doing so for ECDSA is trivial, and can be useful for TLS as well as the future package manager.
2022-10-26std.crypto.sign.ecdsa: accepts unusual parameters like EcdsaP384Sha256 (#13302)Naoki MATSUMOTO
This commit accepts unusual parameters like EcdsaP384Sha256. Some certifictes(below certs are in /etc/ssl/certs/ca-certificates.crt on Ubuntu 22.04) use EcdsaP384Sha256 to sign itself. - Subject: C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions ECC RootCA 2015 - Subject: C=US, ST=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority ECC - Subject: C=US, ST=Texas, L=Houston, O=SSL Corporation, CN=SSL.com Root Certification Authority ECC In verify(), hash array `h` is allocated to be larger than the scalar.encoded_length. The array is regarded as big-endian. Hash values are filled in the back of the array and the rest bytes in front are filled with zero. In sign(), the hash array is allocated and filled as same as verify(). In deterministicScalar(), hash bytes are insufficient to generate `k` To generate `k` without narrowing its value range, this commit uses algorithm stage h. in "Section 3.2 Generation of k" in RFC6979.
2022-07-06crypto.sign.ecdsa: fix toCompressedSec1()/toUnompressedSec1() (#12009)Frank Denis
The Ecdsa.PublicKey type is not a direct alias for a curve element. So, use the inner field containing the curve element for serialization.
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-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.