As you might know, I left Google in spring to try and make the concept of a professional Open Source maintainer a thing. I'm staying on as a maintainer of the Go cryptography standard library, and I am going to seek funding from companies that rely on it, want to ensure its security and reliability, and would like to get a direct line to the maintainers of their critical business infrastructure. (If this sounds like you, reply to this email!)

In the meantime, though, the Go development cycle progresses inexorably, with the Go 1.20 feature freeze coming at the beginning of November. Once the main Go tree freezes, I plan to work on x/crypto/ssh and age, but in the meantime I have a few things I am excited about for Go 1.20.


The most visible change will be the landing the new crypto/ecdh package I proposed and implemented earlier this year. The package provides a safe, []byte-based, easy to use API for Elliptic Curve Diffie-Hellman over Curve25519 and NIST curves (P-256 and company, but no P-224 if we can get away with it).

crypto/ecdh was made possible by a long-running refactor of the elliptic curve implementations in the standard library. Between Go 1.17 and Go 1.19, most critical code was moved to safer low-level APIs under crypto/internal/nistec and crypto/internal/edwards25519, large pieces were replaced with code generated from fiat-crypto's formally verified models, making every curve constant time, most group logic was replaced with modern complete formulas, and even the assembly was massaged to implement the same functions on all architectures and fit the nistec API. Some assembly is gone, actually!

(Here are all the changes. A couple nifty uses of generics in there if you're curious.)

The goal of the package is to replace the major use case for the now-deprecated crypto/elliptic API, which has a hardcoded dependency on the variable-time, large, and complex math/big package. crypto/elliptic is now no more than a compatibility wrapper. Any more advanced uses of crypto/elliptic can switch to which is an exported version of crypto/internal/nistec, or which is an exported version of crypto/internal/edwards25519.

What's left to do in Go 1.20 then?

First, actually landing the new package, which is already submitted! Then, adding and reviewing new tests (including Wycheproof integration by Roland), which actually revealed there are fewer (!!) edge cases than I had originally documented. Finally, reviewing the BoringCrypto integration by Russ.

math/big out of the security perimeter

There is an even broader goal behind this work: moving math/big out of the security perimeter entirely, meaning making it unreachable from attacker-exposed cryptographic APIs and protocols.

math/big is a general-purpose big integer library, it's not constant time, and it's full of complex code that while unnecessary for cryptography has repeatedly led to security vulnerabilities in crypto packages. While it was a convenient way to bootstrap the Go crypto standard library, math/big does not belong in crypto code in 2022.

crypto/ecdh lets us deprecate crypto/elliptic, and lets us bypass math/big in crypto/tls's ECDHE implementation.

The next step is modifying crypto/ecdsa to use crypto/internal/nistec for the group operations on known curves, deprecate the use of custom curves, and replace the scalar field operations with... something. That something might be fiat-crypto field implementations for each scalar field (P-256's, P-384's, and P-521's) with the wide reduction trick we talked about in Cryptography Dispatches, or using a minimal bigint implementation shared with crypto/rsa.

Speaking of, crypto/rsa unavoidably needs a lightweight bigint implementation to replace its dependency on math/big. The good news is that we can make that one constant-time, simple, and tightly scoped for its purposes, which should make it much easier to maintain and keep secure. Lucas contributed one that needs review, and Thomas Pornin offered a Go port of BearSSL's one. This will be a significant amount of assessment, review, and testing work, but it's the last real hurdle.

Finally, we need to worry about the places where big.Int is exposed in public APIs, mainly crypto/rsa and crypto/ecdsa key types. An idea is making the (*Int).SetBytes/(*Int).FillBytes round-trip constant-time so it can be used as just an annoying way to carry around the []byte encoding of the key values. The problems with that are how to handle (or check in constant time) any manual modification to the big.Int, and how to store zero-padded values (which we can't unpad in constant time) without breaking the normalization invariant of big.nat. I welcome suggestions!

If we do go the route of keeping a select subset of math/big exposed, we'll want to lock it in to ensure we can keep it constant time and well reviewed. For that I have a WIP test that does static analysis to ensure only expected functions are reachable from crypto packages.

More elliptic curves

Aside from the math/big-related efforts, there are a couple other Go 1.20 tasks that have to do with elliptic curves.

First, landing a rewrite of the edwards25519 scalar field that replaces the last bits of unreadable ref10 code with fiat-crypto generated code. You can read more on a previous Cryptography Dispatches issue, and there's an overview of the overall edwards25519 rewrite in the CL that landed it after years out-of-tree.

Second, finally landing support for Ed25519ph (the pre-hashed variant of Ed25519) in crypto/ed25519.


Finally, as a stretch goal in case elliptic curve work leaves some space for other things, I collected a couple batches of crypto/tls work. (I find it more efficient to work in topic-scoped batches, so I can load context on a protocol and codebase once and use it to land multiple changes.)

One batch revolves around session resumption: exposing a way to provide external PSKs in TLS 1.3 (which are the underlying mechanism of session tickets in TLS 1.3), maybe implementing PSK modes, implementing Session IDs, making sessions serializable/exportable.

Here's a list of related issues. (The one about forward secrecy by default was already mostly addressed by work we landed somewhat quietly with Katie in Go 1.15, which I'm hoping to write about for the Go blog, as it sets Go significantly apart from any other TLS stack I know about.)

The second batch is a miscellaneous list of crypto/tls work. If you have anything else TLS-related you care about, now is a good time to ping me on it.

The picture

DEF CON was a blast (we won a Black Badge with the Scavenger Hunt!) and systematically eating outdoors and wearing a P100 respirator spared me from COVID. Las Vegas is hell but pretty.

A night-time picture of the Las Vegas skyline taken from a high floor. In the foreground a large road, mostly empty, and two blocks of low buildings and empty space with a couple billboards with bright lights. Mid-frame, a string of high-rise casinos covered in sparkly lights. In the background, pitch black sky.

If you want to stay up to date with my Open Source work, consider following me on Twitter or subscribing to this newsletter if you haven't already! If your company depends on Go and its cryptography libraries, or any other of my Open Source projects, consider sponsoring my maintenance work. Reply to this email, introduce me to the right people, and I'll work with your accounting department to make it happen!