Skip to content

Conversation

@lukechampine
Copy link
Member

@lukechampine lukechampine commented Feb 4, 2026

Revives the version argument the v3 API, allowing the handshake to switch between AES and ChaCha. Benchmarks show a ~4x speedup (how fitting). Also dropped support for covert frames and DialStreamContext; they were previously removed from the package-level API, but not the underlying v3/ implementation.

Implements #28

Copilot AI review requested due to automatic review settings February 4, 2026 22:46
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request revives version-based cipher selection in the v3 API, enabling switching between ChaCha20-Poly1305 (version 3) and AES-GCM (version 4+) for encryption. The PR also removes support for covert frames throughout the codebase. The main motivation is performance: AES-GCM with hardware acceleration (AES-NI) provides approximately 4x speedup compared to ChaCha20-Poly1305.

Changes:

  • Adds peerVersion parameter to v3 API functions for cipher selection
  • Implements newAEAD() function to choose between ChaCha20-Poly1305 (v3) and AES-GCM (v4+)
  • Removes all covert stream functionality including DialCovertStream(), related buffer management, and padding logic
  • Updates package-level API to default to version 4
  • Adds test coverage for multiple versions (3, 4, 5, 255)

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
mux.go Updates version negotiation from 3 to 4, passes negotiated version to v3 layer
v3/handshake.go Implements cipher selection logic based on version, adds newAEAD() function, fixes typo
v3/mux.go Adds peerVersion parameter to handshake functions, removes covert stream methods and buffer management
v3/frame.go Removes covert frame handling logic, updates constant names for generality, uses modern range syntax
v3/mux_test.go Adds version selection test, removes covert stream tests and benchmarks, removes unused imports

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ChrisSchinnerl
ChrisSchinnerl previously approved these changes Feb 6, 2026
Copy link
Member

@peterjan peterjan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

README.md still mentions covert streams

n8mgr
n8mgr previously approved these changes Feb 6, 2026
Copy link
Member

@n8mgr n8mgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit unfortunate that we once again have protocol v4, in v3/*.go, but it makes sense.

There's only ~5% performance loss on my Mac going with AES-256. Since it's fairly negligible, we have the key material, and it's an easy boost I'd probably lean towards 256. I'm good either way and we can always revisit it later.

ChrisSchinnerl
ChrisSchinnerl previously approved these changes Feb 9, 2026
Alrighttt
Alrighttt previously approved these changes Feb 9, 2026
Copy link

@Alrighttt Alrighttt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM;

Tested this manually, and everything works as expected. The only nit I have is that we now have v4 code within the v3 directory.

@lukechampine
Copy link
Member Author

Perhaps we should rename to v4. The only downside is that clients will have to explicitly update their dependency, but that's not the end of the world.

@lukechampine lukechampine dismissed stale reviews from Alrighttt and ChrisSchinnerl via a79e6ae February 9, 2026 17:05
@ChrisSchinnerl
Copy link
Member

ChrisSchinnerl commented Feb 10, 2026

Some additional benchmarks from my Proxmox server. All benchmarks used 1 core but different CPU settings:

The difference between the v2 and v2-AES versions of the virtualized CPUs are supposedly just the AES-NI instruction set. But both lack any instructions added after that such as AVX, AVX2 etc.

  1. With CPU set to "x86-64-v2" (QEMU virtualized)
goos: linux
goarch: amd64
pkg: go.sia.tech/mux/v4
cpu: QEMU Virtual CPU version 2.5+
BenchmarkMux
BenchmarkMux/1
BenchmarkMux/1   	   15434	     78891 ns/op	  54.46 MB/s	     12859 frames/sec	       6 B/op	       0 allocs/op
BenchmarkMux/2
BenchmarkMux/2   	    9930	    156818 ns/op	  54.79 MB/s	     12755 frames/sec	      11 B/op	       0 allocs/op
BenchmarkMux/10
BenchmarkMux/10  	    1570	    781574 ns/op	  54.97 MB/s	     12994 frames/sec	      79 B/op	       0 allocs/op
BenchmarkMux/100
BenchmarkMux/100 	     146	   7943585 ns/op	  54.08 MB/s	     12593 frames/sec	    1223 B/op	       4 allocs/op
BenchmarkMux/500
BenchmarkMux/500 	      27	  41587433 ns/op	  51.65 MB/s	     12028 frames/sec	  121437 B/op	     180 allocs/op
BenchmarkMux/1000
BenchmarkMux/1000         	      14	  83254898 ns/op	  51.60 MB/s	     12013 frames/sec	  468820 B/op	     704 allocs/op
BenchmarkPackets
BenchmarkPackets/1440x1
BenchmarkPackets/1440x1   	   47037	     26645 ns/op	  53.14 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x2
BenchmarkPackets/1440x2   	   22863	     51884 ns/op	  55.05 MB/s	       3 B/op	       0 allocs/op
BenchmarkPackets/1440x3
BenchmarkPackets/1440x3   	   15175	     78563 ns/op	  54.68 MB/s	       6 B/op	       0 allocs/op
BenchmarkPackets/1440x4
BenchmarkPackets/1440x4   	   10000	    103088 ns/op	  55.64 MB/s	      14 B/op	       0 allocs/op
BenchmarkPackets/1440x5
BenchmarkPackets/1440x5   	   10000	    134954 ns/op	  53.17 MB/s	      16 B/op	       0 allocs/op
BenchmarkPackets/1440x6
BenchmarkPackets/1440x6   	   10000	    157152 ns/op	  54.83 MB/s	      19 B/op	       0 allocs/op
BenchmarkPackets/1440x7
BenchmarkPackets/1440x7   	   10000	    181585 ns/op	  55.38 MB/s	      23 B/op	       0 allocs/op
BenchmarkPackets/1440x8
BenchmarkPackets/1440x8   	   10000	    207340 ns/op	  55.45 MB/s	      26 B/op	       0 allocs/op
BenchmarkPackets/1440x9
BenchmarkPackets/1440x9   	   10000	    233517 ns/op	  55.40 MB/s	      28 B/op	       0 allocs/op
BenchmarkPackets/1440x10
BenchmarkPackets/1440x10  	    9237	    255080 ns/op	  56.36 MB/s	      34 B/op	       0 allocs/op
BenchmarkPackets/1440x20
BenchmarkPackets/1440x20  	    2820	    518442 ns/op	  55.50 MB/s	     221 B/op	       0 allocs/op
PASS
ok  	go.sia.tech/mux/v4	28.690s
  1. With CPU set to "x86-64-v2-AES" (QEMU virtualized)
goos: linux
goarch: amd64
pkg: go.sia.tech/mux/v4
cpu: QEMU Virtual CPU version 2.5+
BenchmarkMux
BenchmarkMux/1
BenchmarkMux/1   	   30168	     39267 ns/op	 109.40 MB/s	     25754 frames/sec	       3 B/op	       0 allocs/op
BenchmarkMux/2
BenchmarkMux/2   	   14840	     77371 ns/op	 111.05 MB/s	     26228 frames/sec	       7 B/op	       0 allocs/op
BenchmarkMux/10
BenchmarkMux/10  	    3564	    438929 ns/op	  97.87 MB/s	     23057 frames/sec	      34 B/op	       0 allocs/op
BenchmarkMux/100
BenchmarkMux/100 	     300	   3987600 ns/op	 107.73 MB/s	     25083 frames/sec	    1299 B/op	       2 allocs/op
BenchmarkMux/500
BenchmarkMux/500 	      58	  20199070 ns/op	 106.34 MB/s	     24758 frames/sec	   10896 B/op	      68 allocs/op
BenchmarkMux/1000
BenchmarkMux/1000         	      28	  40813631 ns/op	 105.26 MB/s	     24506 frames/sec	   41503 B/op	     285 allocs/op
BenchmarkPackets
BenchmarkPackets/1440x1
BenchmarkPackets/1440x1   	   97806	     13593 ns/op	 104.17 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x2
BenchmarkPackets/1440x2   	   47589	     26102 ns/op	 109.42 MB/s	       1 B/op	       0 allocs/op
BenchmarkPackets/1440x3
BenchmarkPackets/1440x3   	   33100	     39384 ns/op	 109.08 MB/s	       3 B/op	       0 allocs/op
BenchmarkPackets/1440x4
BenchmarkPackets/1440x4   	   24392	     51184 ns/op	 112.07 MB/s	       5 B/op	       0 allocs/op
BenchmarkPackets/1440x5
BenchmarkPackets/1440x5   	   19207	     63616 ns/op	 112.80 MB/s	       8 B/op	       0 allocs/op
BenchmarkPackets/1440x6
BenchmarkPackets/1440x6   	   15883	     76420 ns/op	 112.75 MB/s	      12 B/op	       0 allocs/op
BenchmarkPackets/1440x7
BenchmarkPackets/1440x7   	   13292	     90885 ns/op	 110.65 MB/s	      16 B/op	       0 allocs/op
BenchmarkPackets/1440x8
BenchmarkPackets/1440x8   	   10000	    102641 ns/op	 112.00 MB/s	      26 B/op	       0 allocs/op
BenchmarkPackets/1440x9
BenchmarkPackets/1440x9   	   10000	    114998 ns/op	 112.49 MB/s	      28 B/op	       0 allocs/op
BenchmarkPackets/1440x10
BenchmarkPackets/1440x10  	   10000	    128008 ns/op	 112.31 MB/s	      32 B/op	       0 allocs/op
BenchmarkPackets/1440x20
BenchmarkPackets/1440x20  	    9218	    259200 ns/op	 111.02 MB/s	      67 B/op	       0 allocs/op
PASS
ok  	go.sia.tech/mux/v4	29.247s
  1. With CPU set to "host" (native but still 1 core)
goos: linux
goarch: amd64
pkg: go.sia.tech/mux/v4
cpu: AMD Ryzen 7 5700X 8-Core Processor             
BenchmarkMux
BenchmarkMux/1
BenchmarkMux/1   	  398554	      3139 ns/op	1368.38 MB/s	    318536 frames/sec	       0 B/op	       0 allocs/op
BenchmarkMux/2
BenchmarkMux/2   	  204283	      6212 ns/op	1383.19 MB/s	    321982 frames/sec	       0 B/op	       0 allocs/op
BenchmarkMux/10
BenchmarkMux/10  	   37765	     35892 ns/op	1196.94 MB/s	    278625 frames/sec	       3 B/op	       0 allocs/op
BenchmarkMux/100
BenchmarkMux/100 	    3646	    325837 ns/op	1318.45 MB/s	    306913 frames/sec	      75 B/op	       0 allocs/op
BenchmarkMux/500
BenchmarkMux/500 	     730	   1643137 ns/op	1307.26 MB/s	    304307 frames/sec	    1690 B/op	       5 allocs/op
BenchmarkMux/1000
BenchmarkMux/1000         	     355	   3394367 ns/op	1265.63 MB/s	    294617 frames/sec	    5958 B/op	      23 allocs/op
BenchmarkPackets
BenchmarkPackets/1440x1
BenchmarkPackets/1440x1   	  930172	      1733 ns/op	 817.28 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x2
BenchmarkPackets/1440x2   	  546501	      2400 ns/op	1190.19 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x3
BenchmarkPackets/1440x3   	  413644	      3135 ns/op	1370.41 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x4
BenchmarkPackets/1440x4   	  280515	      3817 ns/op	1502.90 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x5
BenchmarkPackets/1440x5   	  275025	      4397 ns/op	1632.18 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x6
BenchmarkPackets/1440x6   	  234957	      5521 ns/op	1560.63 MB/s	       0 B/op	       0 allocs/op
BenchmarkPackets/1440x7
BenchmarkPackets/1440x7   	  173286	      6205 ns/op	1620.72 MB/s	       1 B/op	       0 allocs/op
BenchmarkPackets/1440x8
BenchmarkPackets/1440x8   	  173283	      6975 ns/op	1648.11 MB/s	       1 B/op	       0 allocs/op
BenchmarkPackets/1440x9
BenchmarkPackets/1440x9   	  162092	      7549 ns/op	1713.54 MB/s	       1 B/op	       0 allocs/op
BenchmarkPackets/1440x10
BenchmarkPackets/1440x10  	  145899	      8265 ns/op	1739.40 MB/s	       2 B/op	       0 allocs/op
BenchmarkPackets/1440x20
BenchmarkPackets/1440x20  	   73911	     16623 ns/op	1731.15 MB/s	       8 B/op	       0 allocs/op
PASS
ok  	go.sia.tech/mux/v4	23.667s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants