Repository: libp2p/go-libp2p
Pull request #2309 (2023-05-24 10:51:02)

use standard library sha256 implementation for Go 1.21
See rational and benchmarks in multiformats/go-multihash#173.

Fixes: #2308

marten-seemann: @Jorropo Can you please rebase and update go-multihash to v0.2.3? I'd like to include this in the v0.30 release later today, but I can't push to your branch.
Jorropo: @marten-seemann done
Jorropo: Unrelated autorelay failure, rerunning the test suite.

Patch:
diff --git a/core/crypto/ecdsa.go b/core/crypto/ecdsa.go
index c936d502..8e392c9e 100644
--- a/core/crypto/ecdsa.go
+++ b/core/crypto/ecdsa.go
@@ -12,8 +12,7 @@ import (
 
 	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
 	"github.com/libp2p/go-libp2p/core/internal/catch"
-
-	"github.com/minio/sha256-simd"
+	"github.com/libp2p/go-libp2p/internal/sha256"
 )
 
 // ECDSAPrivateKey is an implementation of an ECDSA private key
diff --git a/core/crypto/rsa_go.go b/core/crypto/rsa_go.go
index 8981ba6a..c955cf8e 100644
--- a/core/crypto/rsa_go.go
+++ b/core/crypto/rsa_go.go
@@ -10,8 +10,7 @@ import (
 
 	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
 	"github.com/libp2p/go-libp2p/core/internal/catch"
-
-	"github.com/minio/sha256-simd"
+	"github.com/libp2p/go-libp2p/internal/sha256"
 )
 
 // RsaPrivateKey is a rsa private key
diff --git a/core/crypto/secp256k1.go b/core/crypto/secp256k1.go
index 27544a59..bcd68ac6 100644
--- a/core/crypto/secp256k1.go
+++ b/core/crypto/secp256k1.go
@@ -9,7 +9,7 @@ import (
 
 	"github.com/decred/dcrd/dcrec/secp256k1/v4"
 	"github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
-	"github.com/minio/sha256-simd"
+	"github.com/libp2p/go-libp2p/internal/sha256"
 )
 
 // Secp256k1PrivateKey is a Secp256k1 private key
diff --git a/examples/chat-with-mdns/flags.go b/examples/chat-with-mdns/flags.go
index e188b2ed..4e457062 100644
--- a/examples/chat-with-mdns/flags.go
+++ b/examples/chat-with-mdns/flags.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/chat-with-mdns/main.go b/examples/chat-with-mdns/main.go
index 57b89c25..a0712e89 100644
--- a/examples/chat-with-mdns/main.go
+++ b/examples/chat-with-mdns/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/chat-with-mdns/mdns.go b/examples/chat-with-mdns/mdns.go
index c1f5590e..a953f097 100644
--- a/examples/chat-with-mdns/mdns.go
+++ b/examples/chat-with-mdns/mdns.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/chat-with-rendezvous/chat.go b/examples/chat-with-rendezvous/chat.go
index 5fc8d4e3..b33fd094 100644
--- a/examples/chat-with-rendezvous/chat.go
+++ b/examples/chat-with-rendezvous/chat.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/chat-with-rendezvous/flags.go b/examples/chat-with-rendezvous/flags.go
index a2e8ed1d..3c3430d3 100644
--- a/examples/chat-with-rendezvous/flags.go
+++ b/examples/chat-with-rendezvous/flags.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/chat/chat.go b/examples/chat/chat.go
index cd1c2872..e5c33b14 100644
--- a/examples/chat/chat.go
+++ b/examples/chat/chat.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 /*
  *
  * The MIT License (MIT)
diff --git a/examples/echo/main.go b/examples/echo/main.go
index 3bba8961..6aba1c42 100644
--- a/examples/echo/main.go
+++ b/examples/echo/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/http-proxy/proxy.go b/examples/http-proxy/proxy.go
index 27d95978..78128e25 100644
--- a/examples/http-proxy/proxy.go
+++ b/examples/http-proxy/proxy.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/01-Transports/main.go b/examples/ipfs-camp-2019/01-Transports/main.go
index 0b358f18..9103c9db 100644
--- a/examples/ipfs-camp-2019/01-Transports/main.go
+++ b/examples/ipfs-camp-2019/01-Transports/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/02-Multiaddrs/main.go b/examples/ipfs-camp-2019/02-Multiaddrs/main.go
index dd7f4c38..20698a96 100644
--- a/examples/ipfs-camp-2019/02-Multiaddrs/main.go
+++ b/examples/ipfs-camp-2019/02-Multiaddrs/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/03-Muxing-Encryption/main.go b/examples/ipfs-camp-2019/03-Muxing-Encryption/main.go
index 031b6da2..ea2e6308 100644
--- a/examples/ipfs-camp-2019/03-Muxing-Encryption/main.go
+++ b/examples/ipfs-camp-2019/03-Muxing-Encryption/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/05-Discovery/main.go b/examples/ipfs-camp-2019/05-Discovery/main.go
index 51d5a6fd..03d632ba 100644
--- a/examples/ipfs-camp-2019/05-Discovery/main.go
+++ b/examples/ipfs-camp-2019/05-Discovery/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/05-Discovery/protocol.go b/examples/ipfs-camp-2019/05-Discovery/protocol.go
index 70d22f08..596bb883 100644
--- a/examples/ipfs-camp-2019/05-Discovery/protocol.go
+++ b/examples/ipfs-camp-2019/05-Discovery/protocol.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/06-Pubsub/main.go b/examples/ipfs-camp-2019/06-Pubsub/main.go
index 90345419..6880162c 100644
--- a/examples/ipfs-camp-2019/06-Pubsub/main.go
+++ b/examples/ipfs-camp-2019/06-Pubsub/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/06-Pubsub/protocol.go b/examples/ipfs-camp-2019/06-Pubsub/protocol.go
index 899c62ce..6d86113f 100644
--- a/examples/ipfs-camp-2019/06-Pubsub/protocol.go
+++ b/examples/ipfs-camp-2019/06-Pubsub/protocol.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/07-Messaging/chat.pb.go b/examples/ipfs-camp-2019/07-Messaging/chat.pb.go
index 562290f9..7f513355 100644
--- a/examples/ipfs-camp-2019/07-Messaging/chat.pb.go
+++ b/examples/ipfs-camp-2019/07-Messaging/chat.pb.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: chat.proto
 
diff --git a/examples/ipfs-camp-2019/07-Messaging/main.go b/examples/ipfs-camp-2019/07-Messaging/main.go
index 84840d76..4e8254b5 100644
--- a/examples/ipfs-camp-2019/07-Messaging/main.go
+++ b/examples/ipfs-camp-2019/07-Messaging/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/07-Messaging/protocol.go b/examples/ipfs-camp-2019/07-Messaging/protocol.go
index addfc8e9..02562958 100644
--- a/examples/ipfs-camp-2019/07-Messaging/protocol.go
+++ b/examples/ipfs-camp-2019/07-Messaging/protocol.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/07-Messaging/pubsub.go b/examples/ipfs-camp-2019/07-Messaging/pubsub.go
index f40e7497..64857ed8 100644
--- a/examples/ipfs-camp-2019/07-Messaging/pubsub.go
+++ b/examples/ipfs-camp-2019/07-Messaging/pubsub.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/08-End/chat.pb.go b/examples/ipfs-camp-2019/08-End/chat.pb.go
index 562290f9..7f513355 100644
--- a/examples/ipfs-camp-2019/08-End/chat.pb.go
+++ b/examples/ipfs-camp-2019/08-End/chat.pb.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: chat.proto
 
diff --git a/examples/ipfs-camp-2019/08-End/main.go b/examples/ipfs-camp-2019/08-End/main.go
index bc29152b..a1646929 100644
--- a/examples/ipfs-camp-2019/08-End/main.go
+++ b/examples/ipfs-camp-2019/08-End/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/08-End/protocol.go b/examples/ipfs-camp-2019/08-End/protocol.go
index 02e4b98b..a579be6d 100644
--- a/examples/ipfs-camp-2019/08-End/protocol.go
+++ b/examples/ipfs-camp-2019/08-End/protocol.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/ipfs-camp-2019/08-End/pubsub.go b/examples/ipfs-camp-2019/08-End/pubsub.go
index 2be6b012..249ffce0 100644
--- a/examples/ipfs-camp-2019/08-End/pubsub.go
+++ b/examples/ipfs-camp-2019/08-End/pubsub.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/libp2p-host/host.go b/examples/libp2p-host/host.go
index b1b6790a..d6173cc6 100644
--- a/examples/libp2p-host/host.go
+++ b/examples/libp2p-host/host.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/metrics-and-dashboards/main.go b/examples/metrics-and-dashboards/main.go
index 37eee428..f46d1bc1 100644
--- a/examples/metrics-and-dashboards/main.go
+++ b/examples/metrics-and-dashboards/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/multipro/echo.go b/examples/multipro/echo.go
index 8ea67927..4f089772 100644
--- a/examples/multipro/echo.go
+++ b/examples/multipro/echo.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/multipro/main.go b/examples/multipro/main.go
index f7b1ede5..16847fa7 100644
--- a/examples/multipro/main.go
+++ b/examples/multipro/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/multipro/node.go b/examples/multipro/node.go
index 55b63928..db1750f5 100644
--- a/examples/multipro/node.go
+++ b/examples/multipro/node.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/multipro/pb/p2p.pb.go b/examples/multipro/pb/p2p.pb.go
index a33d5497..b5e53f3a 100644
--- a/examples/multipro/pb/p2p.pb.go
+++ b/examples/multipro/pb/p2p.pb.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: p2p.proto
 
diff --git a/examples/multipro/ping.go b/examples/multipro/ping.go
index c274f5bf..abba610b 100644
--- a/examples/multipro/ping.go
+++ b/examples/multipro/ping.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/pubsub/basic-chat-with-rendezvous/main.go b/examples/pubsub/basic-chat-with-rendezvous/main.go
index 57729ed1..fc234350 100644
--- a/examples/pubsub/basic-chat-with-rendezvous/main.go
+++ b/examples/pubsub/basic-chat-with-rendezvous/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/pubsub/chat/chatroom.go b/examples/pubsub/chat/chatroom.go
index 452cc309..0bf24432 100644
--- a/examples/pubsub/chat/chatroom.go
+++ b/examples/pubsub/chat/chatroom.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/pubsub/chat/main.go b/examples/pubsub/chat/main.go
index 45a103d0..c8d2fe77 100644
--- a/examples/pubsub/chat/main.go
+++ b/examples/pubsub/chat/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/pubsub/chat/ui.go b/examples/pubsub/chat/ui.go
index 413b6d39..087b7428 100644
--- a/examples/pubsub/chat/ui.go
+++ b/examples/pubsub/chat/ui.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/relay/main.go b/examples/relay/main.go
index e8fa8b7b..34c2792e 100644
--- a/examples/relay/main.go
+++ b/examples/relay/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/routed-echo/bootstrap.go b/examples/routed-echo/bootstrap.go
index b09228e8..80aa2679 100644
--- a/examples/routed-echo/bootstrap.go
+++ b/examples/routed-echo/bootstrap.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/routed-echo/main.go b/examples/routed-echo/main.go
index 2f40549b..09b13705 100644
--- a/examples/routed-echo/main.go
+++ b/examples/routed-echo/main.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/go.mod b/go.mod
index c7f85419..2ee0eb88 100644
--- a/go.mod
+++ b/go.mod
@@ -48,7 +48,7 @@ require (
 	github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
 	github.com/prometheus/client_golang v1.14.0
 	github.com/prometheus/client_model v0.4.0
-	github.com/quic-go/quic-go v0.36.3
+	github.com/quic-go/quic-go v0.37.5
 	github.com/quic-go/webtransport-go v0.5.3
 	github.com/raulk/go-watchdog v1.3.0
 	github.com/stretchr/testify v1.8.4
@@ -103,8 +103,7 @@ require (
 	github.com/prometheus/common v0.37.0 // indirect
 	github.com/prometheus/procfs v0.8.0 // indirect
 	github.com/quic-go/qpack v0.4.0 // indirect
-	github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
-	github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
+	github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
 	github.com/syndtr/goleveldb v1.0.0 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
diff --git a/go.sum b/go.sum
index 5cd9e4b3..b8f0b3fe 100644
--- a/go.sum
+++ b/go.sum
@@ -434,12 +434,10 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5
 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
 github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
 github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
-github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE=
-github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
-github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI=
-github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
-github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834=
-github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o=
+github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
+github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
+github.com/quic-go/quic-go v0.37.5 h1:pzkYe8AgaxHi+7KJrYBMF+u2rLO5a9kwyCp2dAsljzk=
+github.com/quic-go/quic-go v0.37.5/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
 github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU=
 github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU=
 github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=
diff --git a/internal/sha256/post_go1_21.go b/internal/sha256/post_go1_21.go
new file mode 100644
index 00000000..98c14b60
--- /dev/null
+++ b/internal/sha256/post_go1_21.go
@@ -0,0 +1,23 @@
+//go:build go1.21
+
+// This package use build tags to select between github.com/minio/sha256-simd
+// for go1.20 and bellow and crypto/sha256 for go1.21 and above.
+// This is used because a fast SHANI implementation of sha256 is only avaiable
+// in the std for go1.21 and above. See https://go.dev/issue/50543.
+// TODO: Once go1.22 releases remove this package and replace all uses
+// with crypto/sha256 because the two supported version of go will have the fast
+// implementation.
+package sha256
+
+import (
+	"crypto/sha256"
+	"hash"
+)
+
+func Sum256(b []byte) [sha256.Size]byte {
+	return sha256.Sum256(b)
+}
+
+func New() hash.Hash {
+	return sha256.New()
+}
diff --git a/internal/sha256/pre_go1_21.go b/internal/sha256/pre_go1_21.go
new file mode 100644
index 00000000..db057333
--- /dev/null
+++ b/internal/sha256/pre_go1_21.go
@@ -0,0 +1,24 @@
+//go:build !go1.21
+
+// This package use build tags to select between github.com/minio/sha256-simd
+// for go1.20 and bellow and crypto/sha256 for go1.21 and above.
+// This is used because a fast SHANI implementation of sha256 is only avaiable
+// in the std for go1.21 and above. See https://go.dev/issue/50543.
+// TODO: Once go1.22 releases remove this package and replace all uses
+// with crypto/sha256 because the two supported version of go will have the fast
+// implementation.
+package sha256
+
+import (
+	"hash"
+
+	"github.com/minio/sha256-simd"
+)
+
+func Sum256(b []byte) [sha256.Size]byte {
+	return sha256.Sum256(b)
+}
+
+func New() hash.Hash {
+	return sha256.New()
+}
diff --git a/p2p/host/basic/basic_host.go b/p2p/host/basic/basic_host.go
index 79f02e2c..71ad3967 100644
--- a/p2p/host/basic/basic_host.go
+++ b/p2p/host/basic/basic_host.go
@@ -792,10 +792,11 @@ func (h *BasicHost) Addrs() []ma.Multiaddr {
 				continue
 			}
 			addrWithCerthash, added := tpt.AddCertHashes(addr)
-			addrs[i] = addrWithCerthash
 			if !added {
 				log.Debug("Couldn't add certhashes to webtransport multiaddr because we aren't listening on webtransport")
+				continue
 			}
+			addrs[i] = addrWithCerthash
 		}
 	}
 	return addrs
@@ -942,17 +943,17 @@ func inferWebtransportAddrsFromQuic(in []ma.Multiaddr) []ma.Multiaddr {
 				// Remove certhashes
 				addr, _ = ma.SplitLast(addr)
 			}
-			webtransportAddrs[addr.String()] = struct{}{}
+			webtransportAddrs[string(addr.Bytes())] = struct{}{}
 			// Remove webtransport component, now it's a multiaddr that ends in /quic-v1
 			addr, _ = ma.SplitLast(addr)
 		}
 
 		if _, lastComponent := ma.SplitLast(addr); lastComponent.Protocol().Code == ma.P_QUIC_V1 {
-			addrStr := addr.String()
-			if _, ok := quicOrWebtransportAddrs[addrStr]; ok {
+			bytes := addr.Bytes()
+			if _, ok := quicOrWebtransportAddrs[string(bytes)]; ok {
 				foundSameListeningAddr = true
 			} else {
-				quicOrWebtransportAddrs[addrStr] = struct{}{}
+				quicOrWebtransportAddrs[string(bytes)] = struct{}{}
 			}
 		}
 	}
@@ -974,7 +975,7 @@ func inferWebtransportAddrsFromQuic(in []ma.Multiaddr) []ma.Multiaddr {
 		if _, lastComponent := ma.SplitLast(addr); lastComponent.Protocol().Code == ma.P_QUIC_V1 {
 			// Convert quic to webtransport
 			addr = addr.Encapsulate(wtComponent)
-			if _, ok := webtransportAddrs[addr.String()]; ok {
+			if _, ok := webtransportAddrs[string(addr.Bytes())]; ok {
 				// We already have this address
 				continue
 			}
diff --git a/p2p/security/noise/handshake.go b/p2p/security/noise/handshake.go
index e1a18e9b..4a235c32 100644
--- a/p2p/security/noise/handshake.go
+++ b/p2p/security/noise/handshake.go
@@ -12,11 +12,11 @@ import (
 
 	"github.com/libp2p/go-libp2p/core/crypto"
 	"github.com/libp2p/go-libp2p/core/peer"
+	"github.com/libp2p/go-libp2p/internal/sha256"
 	"github.com/libp2p/go-libp2p/p2p/security/noise/pb"
 
 	"github.com/flynn/noise"
 	pool "github.com/libp2p/go-buffer-pool"
-	"github.com/minio/sha256-simd"
 	"google.golang.org/protobuf/proto"
 )
 
diff --git a/p2p/transport/quicreuse/connmgr.go b/p2p/transport/quicreuse/connmgr.go
index d3f70de9..60c0daa1 100644
--- a/p2p/transport/quicreuse/connmgr.go
+++ b/p2p/transport/quicreuse/connmgr.go
@@ -145,7 +145,7 @@ func (c *ConnManager) transportForListen(network string, laddr *net.UDPAddr) (re
 		return reuse.TransportForListen(network, laddr)
 	}
 
-	conn, err := listenAndOptimize(network, laddr)
+	conn, err := net.ListenUDP(network, laddr)
 	if err != nil {
 		return nil, err
 	}
@@ -204,7 +204,7 @@ func (c *ConnManager) TransportForDial(network string, raddr *net.UDPAddr) (refC
 	case "udp6":
 		laddr = &net.UDPAddr{IP: net.IPv6zero, Port: 0}
 	}
-	conn, err := listenAndOptimize(network, laddr)
+	conn, err := net.ListenUDP(network, laddr)
 	if err != nil {
 		return nil, err
 	}
@@ -229,12 +229,3 @@ func (c *ConnManager) Close() error {
 	}
 	return c.reuseUDP4.Close()
 }
-
-// listenAndOptimize same as net.ListenUDP, but also calls quic.OptimizeConn
-func listenAndOptimize(network string, laddr *net.UDPAddr) (net.PacketConn, error) {
-	conn, err := net.ListenUDP(network, laddr)
-	if err != nil {
-		return nil, err
-	}
-	return quic.OptimizeConn(conn)
-}
diff --git a/p2p/transport/quicreuse/listener.go b/p2p/transport/quicreuse/listener.go
index cd0e882f..4ee20042 100644
--- a/p2p/transport/quicreuse/listener.go
+++ b/p2p/transport/quicreuse/listener.go
@@ -52,6 +52,7 @@ func newQuicListener(tr refCountedQuicTransport, quicConfig *quic.Config) (*quic
 		addrs:     localMultiaddrs,
 	}
 	tlsConf := &tls.Config{
+		SessionTicketsDisabled: true, // This is set for the config for client, but we set it here as well: https://github.com/quic-go/quic-go/issues/4029
 		GetConfigForClient: func(info *tls.ClientHelloInfo) (*tls.Config, error) {
 			cl.protocolsMu.Lock()
 			defer cl.protocolsMu.Unlock()
@@ -82,7 +83,7 @@ func (l *quicListener) allowWindowIncrease(conn quic.Connection, delta uint64) b
 	l.protocolsMu.Lock()
 	defer l.protocolsMu.Unlock()
 
-	conf, ok := l.protocols[conn.ConnectionState().TLS.ConnectionState.NegotiatedProtocol]
+	conf, ok := l.protocols[conn.ConnectionState().TLS.NegotiatedProtocol]
 	if !ok {
 		return false
 	}
diff --git a/p2p/transport/quicreuse/reuse.go b/p2p/transport/quicreuse/reuse.go
index 1584b292..2940e0d3 100644
--- a/p2p/transport/quicreuse/reuse.go
+++ b/p2p/transport/quicreuse/reuse.go
@@ -51,8 +51,7 @@ func (c *singleOwnerTransport) Close() error {
 }
 
 func (c *singleOwnerTransport) WriteTo(b []byte, addr net.Addr) (int, error) {
-	// Safe because we called quic.OptimizeConn ourselves.
-	return c.packetConn.WriteTo(b, addr)
+	return c.Transport.WriteTo(b, addr)
 }
 
 // Constant. Defined as variables to simplify testing.
@@ -86,8 +85,7 @@ func (c *refcountedTransport) Close() error {
 }
 
 func (c *refcountedTransport) WriteTo(b []byte, addr net.Addr) (int, error) {
-	// Safe because we called quic.OptimizeConn ourselves.
-	return c.packetConn.WriteTo(b, addr)
+	return c.Transport.WriteTo(b, addr)
 }
 
 func (c *refcountedTransport) LocalAddr() net.Addr {
@@ -265,7 +263,7 @@ func (r *reuse) transportForDialLocked(network string, source *net.IP) (*refcoun
 	case "udp6":
 		addr = &net.UDPAddr{IP: net.IPv6zero, Port: 0}
 	}
-	conn, err := listenAndOptimize(network, addr)
+	conn, err := net.ListenUDP(network, addr)
 	if err != nil {
 		return nil, err
 	}
@@ -314,7 +312,7 @@ func (r *reuse) TransportForListen(network string, laddr *net.UDPAddr) (*refcoun
 		}
 	}
 
-	conn, err := listenAndOptimize(network, laddr)
+	conn, err := net.ListenUDP(network, laddr)
 	if err != nil {
 		return nil, err
 	}
diff --git a/p2p/transport/webtransport/multiaddr.go b/p2p/transport/webtransport/multiaddr.go
index d6930af3..bd90638b 100644
--- a/p2p/transport/webtransport/multiaddr.go
+++ b/p2p/transport/webtransport/multiaddr.go
@@ -89,17 +89,23 @@ func IsWebtransportMultiaddr(multiaddr ma.Multiaddr) (bool, int) {
 	certhashCount := 0
 
 	ma.ForEach(multiaddr, func(c ma.Component) bool {
-		if c.Protocol().Code == ma.P_QUIC_V1 && state == init {
-			state = foundUDP
-		}
-		if c.Protocol().Code == ma.P_QUIC_V1 && state == foundUDP {
-			state = foundQuicV1
-		}
-		if c.Protocol().Code == ma.P_WEBTRANSPORT && state == foundQuicV1 {
-			state = foundWebTransport
-		}
-		if c.Protocol().Code == ma.P_CERTHASH && state == foundWebTransport {
-			certhashCount++
+		switch c.Protocol().Code {
+		case ma.P_UDP:
+			if state == init {
+				state = foundUDP
+			}
+		case ma.P_QUIC_V1:
+			if state == foundUDP {
+				state = foundQuicV1
+			}
+		case ma.P_WEBTRANSPORT:
+			if state == foundQuicV1 {
+				state = foundWebTransport
+			}
+		case ma.P_CERTHASH:
+			if state == foundWebTransport {
+				certhashCount++
+			}
 		}
 		return true
 	})


Test patch:
diff --git a/.github/workflows/go-test.yml b/.github/workflows/go-test.yml
index c5cb3efc..8ffbc8c0 100644
--- a/.github/workflows/go-test.yml
+++ b/.github/workflows/go-test.yml
@@ -9,8 +9,8 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        os: [ "ubuntu", "windows", "macos" ]
-        go: ["1.19.x","1.20.x"]
+        os: ["ubuntu", "windows", "macos"]
+        go: ["1.20.x", "1.21.x"]
     env:
       COVERAGES: ""
     runs-on: ${{ fromJSON(vars[format('UCI_GO_TEST_RUNNER_{0}', matrix.os)] || format('"{0}-latest"', matrix.os)) }}
diff --git a/core/crypto/key_test.go b/core/crypto/key_test.go
index 23e96246..44d8b169 100644
--- a/core/crypto/key_test.go
+++ b/core/crypto/key_test.go
@@ -16,10 +16,10 @@ import (
 	. "github.com/libp2p/go-libp2p/core/crypto"
 	pb "github.com/libp2p/go-libp2p/core/crypto/pb"
 	"github.com/libp2p/go-libp2p/core/test"
+	"github.com/libp2p/go-libp2p/internal/sha256"
 
 	"github.com/decred/dcrd/dcrec/secp256k1/v4"
 	secp256k1ecdsa "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa"
-	"github.com/minio/sha256-simd"
 )
 
 func TestKeys(t *testing.T) {
diff --git a/examples/chat/chat_test.go b/examples/chat/chat_test.go
index 1a1cea3c..8bbb6992 100644
--- a/examples/chat/chat_test.go
+++ b/examples/chat/chat_test.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/echo/main_test.go b/examples/echo/main_test.go
index b57f094c..c2167b75 100644
--- a/examples/echo/main_test.go
+++ b/examples/echo/main_test.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/go_121_workaround_test.go b/examples/go_121_workaround_test.go
new file mode 100644
index 00000000..9cbcac65
--- /dev/null
+++ b/examples/go_121_workaround_test.go
@@ -0,0 +1,8 @@
+//go:build go1.21
+
+package main
+
+import "testing"
+
+// Needed so that we run at least one test in Go 1.21 so that our go test command exits successfully
+func TestNothing(t *testing.T) {}
diff --git a/examples/ipfs-camp-2019/go_121_workaround_test.go b/examples/ipfs-camp-2019/go_121_workaround_test.go
new file mode 100644
index 00000000..9cbcac65
--- /dev/null
+++ b/examples/ipfs-camp-2019/go_121_workaround_test.go
@@ -0,0 +1,8 @@
+//go:build go1.21
+
+package main
+
+import "testing"
+
+// Needed so that we run at least one test in Go 1.21 so that our go test command exits successfully
+func TestNothing(t *testing.T) {}
diff --git a/examples/libp2p-host/host_test.go b/examples/libp2p-host/host_test.go
index 989014c5..dca19b35 100644
--- a/examples/libp2p-host/host_test.go
+++ b/examples/libp2p-host/host_test.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/multipro/main_test.go b/examples/multipro/main_test.go
index 545fcf29..bcf0a39b 100644
--- a/examples/multipro/main_test.go
+++ b/examples/multipro/main_test.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/pubsub/basic-chat-with-rendezvous/go_121_workaround_test.go b/examples/pubsub/basic-chat-with-rendezvous/go_121_workaround_test.go
new file mode 100644
index 00000000..9cbcac65
--- /dev/null
+++ b/examples/pubsub/basic-chat-with-rendezvous/go_121_workaround_test.go
@@ -0,0 +1,8 @@
+//go:build go1.21
+
+package main
+
+import "testing"
+
+// Needed so that we run at least one test in Go 1.21 so that our go test command exits successfully
+func TestNothing(t *testing.T) {}
diff --git a/examples/pubsub/chat/go_121_workaround_test.go b/examples/pubsub/chat/go_121_workaround_test.go
new file mode 100644
index 00000000..9cbcac65
--- /dev/null
+++ b/examples/pubsub/chat/go_121_workaround_test.go
@@ -0,0 +1,8 @@
+//go:build go1.21
+
+package main
+
+import "testing"
+
+// Needed so that we run at least one test in Go 1.21 so that our go test command exits successfully
+func TestNothing(t *testing.T) {}
diff --git a/examples/relay/main_test.go b/examples/relay/main_test.go
index d42c5766..5b776f0d 100644
--- a/examples/relay/main_test.go
+++ b/examples/relay/main_test.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package main
 
 import (
diff --git a/examples/testutils/logharness.go b/examples/testutils/logharness.go
index 2f075645..a98eeb4e 100644
--- a/examples/testutils/logharness.go
+++ b/examples/testutils/logharness.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package testutils
 
 import (
diff --git a/examples/testutils/net.go b/examples/testutils/net.go
index d33bd4a1..a5dd8307 100644
--- a/examples/testutils/net.go
+++ b/examples/testutils/net.go
@@ -1,3 +1,5 @@
+//go:build !go1.21
+
 package testutils
 
 import (
diff --git a/p2p/host/basic/basic_host_test.go b/p2p/host/basic/basic_host_test.go
index 1093da31..ecaaeb20 100644
--- a/p2p/host/basic/basic_host_test.go
+++ b/p2p/host/basic/basic_host_test.go
@@ -838,6 +838,11 @@ func TestInferWebtransportAddrsFromQuic(t *testing.T) {
 			in:   []string{"/ip4/0.0.0.0/udp/9999/quic-v1", "/ip4/0.0.0.0/udp/9999/quic-v1/webtransport", "/ip4/1.2.3.4/udp/9999/quic-v1"},
 			out:  []string{"/ip4/0.0.0.0/udp/9999/quic-v1", "/ip4/0.0.0.0/udp/9999/quic-v1/webtransport", "/ip4/1.2.3.4/udp/9999/quic-v1", "/ip4/1.2.3.4/udp/9999/quic-v1/webtransport"},
 		},
+		{
+			name: "Happy Path With CertHashes",
+			in:   []string{"/ip4/0.0.0.0/udp/9999/quic-v1", "/ip4/0.0.0.0/udp/9999/quic-v1/webtransport/certhash/uEgNmb28/certhash/uEgNmb28", "/ip4/1.2.3.4/udp/9999/quic-v1"},
+			out:  []string{"/ip4/0.0.0.0/udp/9999/quic-v1", "/ip4/0.0.0.0/udp/9999/quic-v1/webtransport/certhash/uEgNmb28/certhash/uEgNmb28", "/ip4/1.2.3.4/udp/9999/quic-v1", "/ip4/1.2.3.4/udp/9999/quic-v1/webtransport"},
+		},
 		{
 			name: "Already discovered",
 			in:   []string{"/ip4/0.0.0.0/udp/9999/quic-v1", "/ip4/0.0.0.0/udp/9999/quic-v1/webtransport", "/ip4/1.2.3.4/udp/9999/quic-v1", "/ip4/1.2.3.4/udp/9999/quic-v1/webtransport"},
@@ -877,9 +882,6 @@ func TestInferWebtransportAddrsFromQuic(t *testing.T) {
 			sort.StringSlice(tc.in).Sort()
 			sort.StringSlice(tc.out).Sort()
 			min := make([]ma.Multiaddr, 0, len(tc.in))
-			sort.Slice(tc.in, func(i, j int) bool {
-				return tc.in[i] < tc.in[j]
-			})
 			for _, addr := range tc.in {
 				min = append(min, ma.StringCast(addr))
 			}
diff --git a/p2p/net/swarm/swarm_addr_test.go b/p2p/net/swarm/swarm_addr_test.go
index 2eda0f5d..8ab7d18b 100644
--- a/p2p/net/swarm/swarm_addr_test.go
+++ b/p2p/net/swarm/swarm_addr_test.go
@@ -9,6 +9,7 @@ import (
 	"github.com/libp2p/go-libp2p/core/peer"
 	"github.com/libp2p/go-libp2p/core/peerstore"
 	"github.com/libp2p/go-libp2p/core/test"
+	"github.com/libp2p/go-libp2p/internal/sha256"
 	"github.com/libp2p/go-libp2p/p2p/host/eventbus"
 	"github.com/libp2p/go-libp2p/p2p/net/swarm"
 	swarmt "github.com/libp2p/go-libp2p/p2p/net/swarm/testing"
@@ -18,7 +19,6 @@ import (
 	"github.com/libp2p/go-libp2p/p2p/transport/tcp"
 	webtransport "github.com/libp2p/go-libp2p/p2p/transport/webtransport"
 
-	"github.com/minio/sha256-simd"
 	ma "github.com/multiformats/go-multiaddr"
 	"github.com/multiformats/go-multibase"
 	"github.com/multiformats/go-multihash"
diff --git a/p2p/transport/webtransport/multiaddr_test.go b/p2p/transport/webtransport/multiaddr_test.go
index 4e9d7c33..3f0a3ec0 100644
--- a/p2p/transport/webtransport/multiaddr_test.go
+++ b/p2p/transport/webtransport/multiaddr_test.go
@@ -117,6 +117,7 @@ func TestIsWebtransportMultiaddr(t *testing.T) {
 		{addr: "/ip4/1.2.3.4/udp/60042/quic-v1/webtransport/certhash/" + fooHash, want: true, certhashCount: 1},
 		{addr: "/ip4/1.2.3.4/udp/60042/quic-v1/webtransport/certhash/" + fooHash + "/certhash/" + barHash, want: true, certhashCount: 2},
 		{addr: "/dns4/example.com/udp/60042/quic-v1/webtransport/certhash/" + fooHash, want: true, certhashCount: 1},
+		{addr: "/dns4/example.com/tcp/60042/quic-v1/webtransport/certhash/" + fooHash, want: false},
 		{addr: "/dns4/example.com/udp/60042/webrtc/certhash/" + fooHash, want: false},
 	}
 
diff --git a/test-plans/PingDockerfile b/test-plans/PingDockerfile
index 1f19562d..5c413aa4 100644
--- a/test-plans/PingDockerfile
+++ b/test-plans/PingDockerfile
@@ -1,7 +1,7 @@
 # syntax=docker/dockerfile:1
 # This is run from the parent directory to copy the whole go-libp2p codebase
 
-FROM golang:1.19-alpine AS builder
+FROM golang:1.21-alpine AS builder
 
 WORKDIR /app/
 
@@ -14,4 +14,4 @@ FROM alpine
 WORKDIR /app
 
 COPY --from=builder /testplan /testplan
-ENTRYPOINT [ "/testplan"]
\ No newline at end of file
+ENTRYPOINT [ "/testplan"]
diff --git a/test-plans/go.mod b/test-plans/go.mod
index b3ff3047..c9f5c339 100644
--- a/test-plans/go.mod
+++ b/test-plans/go.mod
@@ -73,9 +73,8 @@ require (
 	github.com/prometheus/common v0.44.0 // indirect
 	github.com/prometheus/procfs v0.10.1 // indirect
 	github.com/quic-go/qpack v0.4.0 // indirect
-	github.com/quic-go/qtls-go1-19 v0.3.3 // indirect
-	github.com/quic-go/qtls-go1-20 v0.2.3 // indirect
-	github.com/quic-go/quic-go v0.36.3 // indirect
+	github.com/quic-go/qtls-go1-20 v0.3.1 // indirect
+	github.com/quic-go/quic-go v0.37.5 // indirect
 	github.com/quic-go/webtransport-go v0.5.3 // indirect
 	github.com/raulk/go-watchdog v1.3.0 // indirect
 	github.com/spaolacci/murmur3 v1.1.0 // indirect
diff --git a/test-plans/go.sum b/test-plans/go.sum
index 6d818b1e..7ffc7e63 100644
--- a/test-plans/go.sum
+++ b/test-plans/go.sum
@@ -238,12 +238,10 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi
 github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
 github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
 github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
-github.com/quic-go/qtls-go1-19 v0.3.3 h1:wznEHvJwd+2X3PqftRha0SUKmGsnb6dfArMhy9PeJVE=
-github.com/quic-go/qtls-go1-19 v0.3.3/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
-github.com/quic-go/qtls-go1-20 v0.2.3 h1:m575dovXn1y2ATOb1XrRFcrv0F+EQmlowTkoraNkDPI=
-github.com/quic-go/qtls-go1-20 v0.2.3/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
-github.com/quic-go/quic-go v0.36.3 h1:f+yOqeGhMoRX7/M3wmEw/djhzKWr15FtQysox85/834=
-github.com/quic-go/quic-go v0.36.3/go.mod h1:qxQumdeKw5GmWs1OsTZZnOxzSI+RJWuhf1O8FN35L2o=
+github.com/quic-go/qtls-go1-20 v0.3.1 h1:O4BLOM3hwfVF3AcktIylQXyl7Yi2iBNVy5QsV+ySxbg=
+github.com/quic-go/qtls-go1-20 v0.3.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
+github.com/quic-go/quic-go v0.37.5 h1:pzkYe8AgaxHi+7KJrYBMF+u2rLO5a9kwyCp2dAsljzk=
+github.com/quic-go/quic-go v0.37.5/go.mod h1:YsbH1r4mSHPJcLF4k4zruUkLBqctEMBDR6VPvcYjIsU=
 github.com/quic-go/webtransport-go v0.5.3 h1:5XMlzemqB4qmOlgIus5zB45AcZ2kCgCy2EptUrfOPWU=
 github.com/quic-go/webtransport-go v0.5.3/go.mod h1:OhmmgJIzTTqXK5xvtuX0oBpLV2GkLWNDA+UeTGJXErU=
 github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk=