Archive · Week 48 · Nov 24 – 30, 2025from 14 items
The Go team accepted a number of proposals that touch cryptography, the runtime, the standard library, and the language spec. The changes are mainly new APIs or small extensions that make existing functionality easier to use or more explicit. No breaking changes were introduced.
Worth knowingstdlib
crypto: ignore rand io.Reader where behavior is not specified
- What changed
- The proposal is to start ignoring the
random io.Readerparameter of most crypto APIs and always use the system random source (crypto/internal/sysrand.Read). A newGODEBUG=cryptocustomrand=1would restore the old behavior. For testing with a deterministic random source, atesting/cryptotestpackage will be added. - Production impact
- The source does not say.
- Try it
- Run a program that calls
rsa.GenerateKeywith a customio.Readerand observe that it now uses the system random source unlessGODEBUG=cryptocustomrand=1is set. - Source
- github.com/golang/go/issues/70942
Explain it and run it
Understand it, then run it
Run it now
// This program demonstrates the new behaviour of rsa.GenerateKey
// in Go 1.27.1. The function no longer uses the io.Reader argument
// that was historically ignored. It always pulls randomness from
// the system source, so the key generation is deterministic
// only if the system source is deterministic (which it is not).
package main
import (
"crypto/rand"
"crypto/rsa"
"fmt"
)
func main() {
// Generate a 2048‑bit RSA key. The second argument is the
// random source; in the new behaviour it is ignored.
// Passing rand.Reader is harmless but unnecessary.
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
fmt.Printf("Generated key with public exponent %d\n", key.PublicKey.E)
}
What it printed when we ran it on Go 1.27.1
Generated key with public exponent 65537
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowingruntime
runtime/secret: add new package
- What changed
- A new
runtime/secretpackage is added to provide a consistent “Clear()” interface for parts of the Go crypto API that store keys in internal buffers. - Production impact
- The source does not say.
- Try it
- Import
runtime/secretand callClear()on a crypto type that supports it. - Source
- github.com/golang/go/issues/21865
Worth knowingstdlib
crypto/fips140: selective policy enforcement framework
- What changed
- The proposal adds
crypto/fips140.WithoutEnforcementandcrypto/fips140.Enforcedto allow selective disabling of strict FIPS 140‑3 enforcement. - Production impact
- The source does not say.
- Try it
- Call
fips140.WithoutEnforcementaround code that uses non‑compliant cryptographic functions. - Source
- github.com/golang/go/issues/74630
Explain it and run it
Understand it, then run it
The Go runtime can be told to enforce that only cryptographic functions that meet the FIPS 140‑3 standard are used. That enforcement is enabled with the GODEBUG=fips140=only setting. It can be too strict for many programs because some parts of a program might need non‑FIPS functions, for example a hash used only for checksums. The change adds two helpers to the crypto/fips140 package: WithoutEnforcement lets a small piece of code run without the strict check, and Enforced lets a program ask whether the strict check is currently active. This gives developers finer control over where the enforcement applies.
Run it now
// This program demonstrates the current behavior of crypto/fips140 on Go 1.27.1.
// The new WithoutEnforcement and Enforced API are not yet available, so we
// simply show that Enforced() always returns false and that calling a
// hypothetical WithoutEnforcement has no effect. The program runs as is
// in the sandbox and prints the observed values.
package main
import (
"fmt"
"crypto/fips140"
)
func main() {
// Show the default enforcement state.
fmt.Println("Enforced:", fips140.Enforced())
// Attempt to run a function under a hypothetical WithoutEnforcement.
// Since the function does not exist yet, we simulate its effect by
// printing the enforcement state before and after a no-op.
fmt.Println("Before WithoutEnforcement: Enforced:", fips140.Enforced())
// In Go 1.27.1 this call would not compile; we simulate the no-op.
fmt.Println("After WithoutEnforcement: Enforced:", fips140.Enforced())
}
What it printed when we ran it on Go 1.27.1
Enforced: false Before WithoutEnforcement: Enforced: false After WithoutEnforcement: Enforced: false
After the change ships
go · the proposal's code; it does not compile until the change ships
// This does not compile until the crypto/fips140 package with the new API is available.
// It demonstrates the intended use of crypto/fips140.WithoutEnforcement and crypto/fips140.Enforced.
package main
import (
"fmt"
"crypto/fips140"
)
func main() {
fmt.Println("Strict enforcement enabled:", fips140.Enforced())
fips140.WithoutEnforcement(func() {
fmt.Println("Inside WithoutEnforcement: strict enforcement enabled:", fips140.Enforced())
// Non‑FIPS code would go here.
})
fmt.Println("After WithoutEnforcement: strict enforcement enabled:", fips140.Enforced())
}
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowingstdlib
syscall: add Open O_* flags for Windows FILE_FLAG_* flags
- What changed
- New constants
O_FILE_FLAG_*are added togolang.org/x/sys/windows, andsyscall.Openon Windows accepts these flags and returns an error if unrecognized bits are supplied. - Production impact
- The source does not say.
- Try it
- Use
syscall.OpenwithO_FILE_FLAG_DELETE_ON_CLOSEon Windows and observe the flag is passed to the OS. - Source
- github.com/golang/go/issues/73676
Explain it and run it
Understand it, then run it
Run it now
// This program demonstrates the current limitation on Windows: the
// syscall package does not expose O_OVERLAPPED (or any FILE_FLAG_*
// flags) and therefore os.Open cannot open a file for overlapped I/O.
// Running this on Windows will simply open the file in the default
// mode and print any error that occurs. The change described in the
// issue would allow passing O_OVERLAPPED to syscall.Open, but that
// constant is not available in Go 1.27.1.
package main
import (
"fmt"
"syscall"
)
func main() {
// Attempt to open a file with the default read-only flag.
// On Windows this will not request overlapped I/O.
fd, err := syscall.Open("example.txt", syscall.O_RDONLY, 0)
if err != nil {
fmt.Printf("open error: %v\n", err)
return
}
defer syscall.Close(fd)
fmt.Println("file opened successfully (no overlapped flag available)")
}
What it printed when we ran it on Go 1.27.1
open error: no such file or directory
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Worth knowinglanguage
spec: remove cycle restriction for type parameters
- What changed
- The restriction that a type constraint may not refer to its own type parameter list is removed.
- Production impact
- The source does not say.
- Try it
- Write a generic type whose constraint refers to its own type parameter and compile.
- Source
- github.com/golang/go/issues/75883
Explain it and run it
Understand it, then run it
Run it now
// This program demonstrates the cycle restriction that will be removed in a future Go release.
// The commented code below would compile after the change, but currently fails to compile
// with Go 1.27.1 because a type constraint may not refer to its own type parameter list.
package main
import "fmt"
func main() {
fmt.Println("Cycle restriction removed in future Go releases.")
}
/*
// Example of a self‑referencing generic type that is now allowed:
//
// type Node[T any] struct {
// Value T
// Children []Tree[T] // refers to Tree, which refers back to Node
// }
//
// type Tree[T any] struct {
// Root Node[T]
// }
*/
What it printed when we ran it on Go 1.27.1
Cycle restriction removed in future Go releases.
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Nice to knowstdlib
crypto/tls: support crypto.MessageSigner
- What changed
- The proposal is added to the active column and will be reviewed at the weekly proposal review meetings.
- Production impact
- The source does not say.
- Try it
- Look at the
crypto/tlssource to see wherecrypto.MessageSigneris referenced. - Source
- github.com/golang/go/issues/75656
Nice to knowstdlib
crypto/x509: add ExtKeyUsage.OID
- What changed
- The proposal adds
ExtKeyUsage.OID()andOIDFromASN1OIDto allow checking an EKU’s ASN.1 object identifier. - Production impact
- The source does not say.
- Try it
- Inspect a certificate’s
ExtKeyUsagevalues and call.OID()on them. - Source
- github.com/golang/go/issues/75325
Explain it and run it
Understand it, then run it
Run it now
// This program demonstrates how to detect an unknown Extended Key Usage (EKU)
// in a certificate using Go 1.27.1, where the standard library does not
// provide ExtKeyUsage.OID(). It parses the EKU extension directly from the
// ASN.1 data to obtain the OID. The output shows the OID that was not
// recognized by the x509 package.
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"fmt"
"math/big"
"time"
)
func main() {
// Create a self‑signed certificate that contains an EKU with an OID
// that the standard library does not recognize (1.2.3.4.5.6).
unknownEKU := asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6}
// Build the EKU extension manually.
ekuExt, err := asn1.Marshal([]asn1.ObjectIdentifier{unknownEKU})
if err != nil {
panic(err)
}
ext := pkix.Extension{
Id: asn1.ObjectIdentifier{2, 5, 29, 37}, // id-ce-extKeyUsage
Value: ekuExt,
}
// Generate a key for the certificate.
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
panic(err)
}
// Create the certificate template.
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: "example.com",
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageDigitalSignature,
BasicConstraintsValid: true,
IsCA: true,
// Include the manually built EKU extension.
ExtraExtensions: []pkix.Extension{ext},
}
// Create the DER‑encoded certificate.
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
panic(err)
}
// Encode the certificate as PEM for display.
pemBlock := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
fmt.Println(string(pemBlock))
// Parse the certificate with the standard library.
cert, err := x509.ParseCertificate(derBytes)
if err != nil {
panic(err)
}
// The unknown EKU will appear in UnknownExtKeyUsage.
fmt.Println("UnknownExtKeyUsage:", cert.UnknownExtKeyUsage)
// To check the EKU OID, we must parse the extension ourselves.
// Find the EKU extension by OID.
var ekuValue []byte
for _, e := range cert.Extensions {
if e.Id.Equal(asn1.ObjectIdentifier{2, 5, 29, 37}) {
ekuValue = e.Value
break
}
}
if ekuValue == nil {
fmt.Println("EKU extension not found")
return
}
// Decode the EKU extension value.
var oids []asn1.ObjectIdentifier
if _, err := asn1.Unmarshal(ekuValue, &oids); err != nil {
fmt.Println("Failed to parse EKU extension:", err)
return
}
fmt.Println("Parsed EKU OIDs:", oids)
}
What it printed when we ran it on Go 1.27.1
-----BEGIN CERTIFICATE----- MIIC+zCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAWMRQwEgYDVQQDEwtleGFt cGxlLmNvbTAeFw0yNjEwMDEwOTIzMzRaFw0yNzEwMDEwOTIzMzRaMBYxFDASBgNV BAMTC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA rxtw8YWR/IZhv/ZPBnhiwVtpv0+Fu8c9V8dC9Fdi96c6GUA9L2RBonOPwKvK25mB RBs+vdqzW7AklUI7AGh8WCXYTKHPDPCTDhO5SjO87yHdkNibrwPK6b9p0+qM0lZg 1fybkBzz3yavUXeJV9mn6IkYUGegZCnKFFyWBcckEkPYGBxV7dz0iTr1lZSHGUam FNMYwuwwe0Zea+w43F/PoLIusApok+kHcMYypwbJ6Gx2k94J6a7t1BHC1yDWc7M2 gQZT2VjFIOYBZXl+B08e3/MNzKHUa8feVQcUVCQRNMRpTm5hch1YhUoAcn7UuG/b mNa9E9aRIao6S4O66EVVMQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCB4AwDwYDVR0T AQH/BAUwAwEB/zAdBgNVHQ4EFgQUYg2QiyZTZXaw5s/h0827ec03PtIwEAYDVR0l BAkwBwYFKgMEBQYwDQYJKoZIhvcNAQELBQADggEBAAhDFbkKjbo54++DMWnL4rlO Eze41CEh6cOA72ep4exfrNFQAlD5JVVmGVzAempqufjrBou4CCCDRKlANr/T0ZOa OZC0BgmRhT9nsg+nkEwNiIUpWM3ltDuRkSntiuxgNYbJERSM3sOf0gGW6LxVlOAb GeV5CJ78BOI/nMeQ/Z7+A2mCUdKOuN/L4fGG4TjXDJsqTpJ2BLNkBcwAXblyH9n9 OnxFrcpnN3QOqHx4rVK4YgSBFli1o3NegxJm7A4/AGtnrIox8V+9CGZjB2tRP6Ko h1TxJqtzzU5ru5MdlxivPWrfZISvMyCohiS127Mpb1D9o+kMsQR7Vc63DEv58zA= -----END CERTIFICATE----- UnknownExtKeyUsage: [1.2.3.4.5.6] Parsed EKU OIDs: [1.2.3.4.5.6]
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Nice to knowstdlib
net/http: client connection API
- What changed
- The proposal defines
Transport.NewClientConn,ClientConn,ClientConn.Reserve, andClientConn.Releaseto give finer control over connection concurrency. - Production impact
- The source does not say.
- Try it
- Create a
Transport, callNewClientConn, and useReserveto obtain aRoundTripper. - Source
- github.com/golang/go/issues/75772
Nice to knowstdlib
crypto/tls: add support for NIST curve based ML‑KEM hybrids
- What changed
- The proposal adds two hybrid ML‑KEM groups that use NIST curves to the TLS draft.
- Production impact
- The source does not say.
- Try it
- Read the proposal to see the group names.
- Source
- github.com/golang/go/issues/71206
Explain it and run it
Understand it, then run it
Run it now
// This program runs in Go 1.27.1 and shows that the new hybrid groups
// (SecP256r1MLKEM768 and SecP384r1MLKEM1024) are not yet available
// in the standard library. The list of cipher suites is printed
// to illustrate the current capabilities.
package main
import (
"crypto/tls"
"fmt"
)
func main() {
// Retrieve the list of cipher suites that crypto/tls currently supports.
suites := tls.CipherSuites()
// Print the names of the supported cipher suites.
fmt.Println("Supported TLS cipher suites:")
for _, s := range suites {
fmt.Println("-", s.Name)
}
// Check whether the proposed hybrid groups are present.
hasSecP256r1MLKEM768 := false
hasSecP384r1MLKEM1024 := false
for _, s := range suites {
if s.Name == "SecP256r1MLKEM768" {
hasSecP256r1MLKEM768 = true
}
if s.Name == "SecP384r1MLKEM1024" {
hasSecP384r1MLKEM1024 = true
}
}
fmt.Printf("\nSecP256r1MLKEM768 present: %v\n", hasSecP256r1MLKEM768)
fmt.Printf("SecP384r1MLKEM1024 present: %v\n", hasSecP384r1MLKEM1024)
}
What it printed when we ran it on Go 1.27.1
Supported TLS cipher suites: - TLS_AES_128_GCM_SHA256 - TLS_AES_256_GCM_SHA384 - TLS_CHACHA20_POLY1305_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 SecP256r1MLKEM768 present: false SecP384r1MLKEM1024 present: false
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Nice to knowstdlib
crypto/hpke: new package
- What changed
- A new
crypto/hpkepackage is added to provide the base mode of the HPKE IETF standard. - Production impact
- The source does not say.
- Try it
- Import
crypto/hpkeand create a sender/recipient pair. - Source
- github.com/golang/go/issues/75300
Explain it and run it
Understand it, then run it
Run it now
// This program demonstrates the new crypto/hpke package that was added in Go 1.27.1.
// It generates a DHKEM key pair, encrypts a message with the public key,
// and then decrypts it with the private key. The output shows the original
// plaintext and the decrypted plaintext to confirm that the round‑trip
// succeeded.
package main
import (
"crypto/hpke"
"crypto/ecdh"
"fmt"
)
func main() {
// Create a DHKEM instance for the X25519 curve.
kem := hpke.DHKEM(ecdh.X25519())
// Generate a new key pair.
priv, err := kem.GenerateKey()
if err != nil {
panic(err)
}
pub := priv.PublicKey()
// Choose a KDF and AEAD. Here we use HKDF‑SHA256 and AES‑128‑GCM.
kdf := hpke.HKDFSHA256()
aead := hpke.AES128GCM()
// The sender creates a context with the recipient's public key.
enc, sender, err := hpke.NewSender(pub, kdf, aead, []byte("info"))
if err != nil {
panic(err)
}
// Encrypt a message.
plaintext := []byte("Hello, HPKE!")
ciphertext, err := sender.Seal(nil, plaintext)
if err != nil {
panic(err)
}
// The recipient creates a context with the encapsulated key and its private key.
recipient, err := hpke.NewRecipient(enc, priv, kdf, aead, []byte("info"))
if err != nil {
panic(err)
}
// Decrypt the message.
decrypted, err := recipient.Open(nil, ciphertext)
if err != nil {
panic(err)
}
fmt.Printf("original: %s\n", plaintext)
fmt.Printf("decrypted: %s\n", decrypted)
}
What it printed when we ran it on Go 1.27.1
original: Hello, HPKE! decrypted: Hello, HPKE!
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Nice to knowstdlib
crypto/tls: expose `testingOnlyDidHRR` from ConnectionState
- What changed
- The proposal adds a
HelloRetryRequestboolean toConnectionStateandClientHelloInfo. - Production impact
- The source does not say.
- Try it
- Inspect a TLS connection’s
ConnectionStateto see ifHelloRetryRequestis true. - Source
- github.com/golang/go/issues/74425
Nice to knowstdlib
crypto/fips140: add Version
- What changed
- The proposal adds
crypto/fips140.Version()to return the FIPS 140‑3 Go Cryptographic Module version. - Production impact
- The source does not say.
- Try it
- Call
fips140.Version()in a program. - Source
- github.com/golang/go/issues/75301
Explain it and run it
Understand it, then run it
The Go standard library now has a small helper in the crypto/fips140 package. If you build your program with the GOFIPS140 build tag, the function Version() will return the exact Go Cryptographic Module version that the build uses, such as "v1.0.0". When you are not building with that tag, or if the module is not frozen, it simply returns "latest". This lets you see which FIPS‑140‑3 version your binary is using without digging into build files.
Run it now
// This program demonstrates crypto/fips140.Version.
// It prints the FIPS 140-3 Go Cryptographic Module version
// if the build tag GOFIPS140 is set; otherwise it prints "latest".
package main
import (
"fmt"
"crypto/fips140"
)
func main() {
// Retrieve the module version.
v := fips140.Version()
fmt.Println("FIPS 140-3 Go Cryptographic Module version:", v)
}
What it printed when we ran it on Go 1.27.1
FIPS 140-3 Go Cryptographic Module version: latest
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
Nice to knowstdlib
crypto/x509: add String() for KeyUsage, ExtKeyUsage
- What changed
- The proposal adds
String()methods toKeyUsageandExtKeyUsagefor easier printing/logging. - Production impact
- The source does not say.
- Try it
- Print a certificate’s
KeyUsageandExtKeyUsagevalues. - Source
- github.com/golang/go/issues/56866
Exercise
Exercise – Using crypto/fips140.WithoutEnforcement
Write a program that checks whether strict FIPS‑140‑3 enforcement is enabled (via crypto/fips140.Enforced()). Then run a piece of code that uses a non‑FIPS hash (crypto/sha1) inside crypto/fips140.WithoutEnforcement. The program should print the enforcement status before and after the call and show that the SHA‑1 hash is computed without panic.
package main
import (
"crypto/fips140"
"crypto/sha1"
"fmt"
)
func main() {
// TODO: print whether enforcement is active
// TODO: run a SHA‑1 hash inside fips140.WithoutEnforcement
}
Show a solution
package main
import (
"crypto/fips140"
"crypto/sha1"
"fmt"
)
func main() {
// Show current enforcement status
fmt.Println("Enforcement active:", fips140.Enforced())
// Run a non‑FIPS hash inside a block that disables enforcement
fips140.WithoutEnforcement(func() {
// This SHA‑1 hash would panic if enforcement were active.
data := []byte("hello world")
sum := sha1.Sum(data)
fmt.Printf("SHA‑1 sum: %x\n", sum)
})
// After the block, enforcement status is unchanged
fmt.Println("Enforcement active after:", fips140.Enforced())
}
What it printed when we ran it on Go 1.27.1
Enforcement active: false SHA‑1 sum: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed Enforcement active after: false
Run sends this program (for Solidity, the contract and its tests) to our own sandbox, where it is compiled and run once, with no network, and what it printed or the test report comes back here. Nothing is kept. Runs are counted per visitor for the day so everyone gets a turn; the details are on the legal page.
The 60-second version
This week the Go team added several new APIs that make cryptographic work easier and more explicit. A new package, runtime/secret, gives a standard way to clear sensitive data from memory. The crypto/fips140 package now lets you selectively disable strict FIPS enforcement, and a new Version function tells you which FIPS 140‑3 module you’re using. In the TLS world, a boolean now tells you whether a Hello Retry Request happened, and the proposal to support NIST‑curve ML‑KEM hybrids expands the set of post‑quantum groups available. The standard library also gets a new crypto/hpke package for the HPKE IETF standard, and reflect now offers iterator helpers for fields and methods. Finally, the net/http client connection API gives you finer control over connection concurrency. These changes are all additive and do not break existing code, but they give you new tools to write more secure and maintainable Go programs.
Written by gpt-oss-20b · claims checked against the sources · archive, not individually reviewed