Skip to content

tls 1.8.2

Choose a tag to compare

@Mosaad-M Mosaad-M released this 08 Oct 18:05
· 5 commits to master since this release
2c358b9

Fast ChaCha20-Poly1305, and TLS 1.2 records built whole. No API change.

ChaCha20-Poly1305 is the TLS 1.3 suite servers choose for clients without AES hardware. It was 25× slower than AES-GCM in tls; now it runs at Python/OpenSSL's speed on the same benchmark.

Performance (Apple M1 Pro)

1.8.2 1.8.1 Python (OpenSSL)
ChaCha20 alone, 16 KiB 1,705 MB/s 40 MB/s
Poly1305 alone, 16 KiB 2,171 MB/s 738 MB/s
ChaCha20-Poly1305 seal / open, 16 KiB ~930 / ~935 MB/s 37 / 37 MB/s
recv loop over TLS_CHACHA20_POLY1305_SHA256 735–746 MB/s ~37 MB/s 695–732 MB/s (same server)
  • ChaCha20:
    • 16 blocks per step on SIMD vectors (lane i holds block i), so the rounds are the scalar code on vectors: add, rotate, xor;
    • 4-block steps for the tail keep short records cheap.
  • Poly1305: 44-bit limbs with 64×64→128-bit multiplies, two blocks per step (h = (h+m₁)·r² + m₂·r).
  • AEAD: AAD, ciphertext and lengths stream into Poly1305 with no MAC-input buffer. Records are sealed and opened in place.
  • Portability: portable Mojo with no intrinsics, so the same code runs on ARM and x86 and in software-AES builds.
  • TLS 1.2: records are built whole in one buffer, so send, close and alerts copy one time less.

Security

  • Constant time: only additions, rotations, xors, masks and fixed multiplies. ct-check gives t = 0.9 for ChaCha20-Poly1305.
  • Forged records: opening a record verifies the tag before decrypting, so a forged record writes nothing.

Testing

  • Oracle: the scalar 1.8.1 implementation is kept as a test oracle. The new code is compared against it:

    • ChaCha20 at every step boundary, counters near 2^32 wraparound, in place;
    • Poly1305 on 2,000 random cases plus extreme limb values;
    • the AEAD with AAD of 0–64 bytes, in place, and a forged tag.

    This runs on ARM (macOS CI) and x86 (Linux CI).

  • Results:

    • 438 tests pass, plus the software-AES job;
    • interop passes, including ChaCha20 and KeyUpdate;
    • fuzzing is clean;
    • live: 24 sites plus 4 bad endpoints correctly rejected, and 55 of 55 in the wide sweep.
  • Dependents: requests, websocket, pg (including SCRAM over a scram-only cluster) and mojo-pkg pass.