dank074 / Discord-video-stream

Experiment for making video streaming work for discord selfbots.
183 stars 35 forks source link

Encryption update #101

Closed dank074 closed 1 month ago

dank074 commented 2 months ago

Adds support for both aead_aes256_gcm_rtpsize and aead_xchacha20_poly1305_rtpsize

Closes https://github.com/dank074/Discord-video-stream/issues/99

longnguyen2004 commented 2 months ago

I'm wondering about whether to include AES-256, since most sources I found seem to indicate that AES-256 is slower than XChaCha20 (unless AES-NI is used, but I don't know if Node.js even utilizes that). Will do some real world tests on my 14 years old CPU to see if there's a real impact.

For context, my current setup can easily handle streams up to 10Mbps, which is Discord's limit.

dank074 commented 2 months ago

I'm wondering about whether to include AES-256, since most sources I found seem to indicate that AES-256 is slower than XChaCha20 (unless AES-NI is used, but I don't know if Node.js even utilizes that). Will do some real world tests on my 14 years old CPU to see if there's a real impact.

For context, my current setup can easily handle streams up to 10Mbps, which is Discord's limit.

Cool I'll wait for your results. We can definitely remove AES-255 support if it's slower since according to the Discord docs it might not always be available on their end anyway. Not sure why it's their preferred option

dank074 commented 1 month ago

We are about ~1 month from our current encryption being deprecated, so I guess we gotta merge this soon. Have you had the chance to do some performance tests yet @longnguyen2004

longnguyen2004 commented 1 month ago

Here are some benchmark results with openssl speed

Block Size 2B 31B 136B 1KiB 8KiB 16KiB
AES-256-GCM (without AES-NI) 4.76MiB/s 50.38MiB/s 169.23MiB/s 399.57MiB/s 460.91MiB/s 463.67MiB/s
ChaCha20-Poly1305 4.95MiB/s (1.04x) 66.28MiB/s (1.32x) 205.59MiB/s (1.21x) 1.18GiB/s (3.01x) 2.01GiB/s (4.47x) 2.12GiB/s (4.69x)
AES-256-GCM (with AES-NI) 12.03MiB/s (2.53x) 130.21MiB/s (2.58x) 513.4MiB/s (3.03x) 2.11GiB/s (5.41x) 3.57GiB/s (7.93x) 3.79GiB/s (8.37x)
Block Size 2B 31B 136B 1KiB 8KiB 16KiB
AES-256-GCM (without AES-NI) 1.08MiB/s 13.47MiB/s 38.76MiB/s 76.14MiB/s 85.4MiB/s 85.45MiB/s
ChaCha20-Poly1305 1.56MiB/s (1.44x) 23.46MiB/s (1.74x) 71.77MiB/s (1.85x) 236.51MiB/s (3.11x) 297.14MiB/s (3.48x) 302.41MiB/s (3.54x)

Commands used for benchmarking:

$ OPENSSL_ia32cap="~0x200000000000000" openssl speed -elapsed -aead -evp aes-256-gcm
$ openssl speed -elapsed -aead -evp chacha20-poly1305
$ openssl speed -elapsed -aead -evp aes-256-gcm

Overall, ChaCha20-Poly1305 is faster than non-accelerated AES-256-GCM. I also saw this with my crude real-world test using a 10Mbps stream on the i3-330M. ChaCha20-Poly1305 has a pretty consistent 2-3% CPU usage, while AES-256-GCM is 3-4.5%, with occasional spikes of 6-11%.

As expected, AES-NI blows everything out of the water, and would be the ideal solution for supported CPUs, which is the majority of CPU produced within the last decade. For those that don't, the impact is also not as much as I thought, and is perfectly adequate for a single stream, so it's probably fine to leave AES in, and add an option to force ChaCha20 somewhere.

dank074 commented 1 month ago

Sounds good, I'll add a config option