Skip to content

Add ChaCha20-Poly1305 cipher and SFTP write-chunk negotiation#174

Merged
Di3Z1E merged 15 commits into
mainfrom
dev-0.7.0
May 16, 2026
Merged

Add ChaCha20-Poly1305 cipher and SFTP write-chunk negotiation#174
Di3Z1E merged 15 commits into
mainfrom
dev-0.7.0

Conversation

@Di3Z1E

@Di3Z1E Di3Z1E commented May 16, 2026

Copy link
Copy Markdown
Collaborator

Description

Implements the chacha20-poly1305@openssh.com cipher in the crypto backend and integrates
it into both the sync and async packet paths in the transport layer. Also adds strict-KEX
state reset on the async receive path, and negotiates the limits@openssh.com SFTP
extension to enable larger write chunks for better throughput.

Fixes # (issue)

Type of Change

Select exactly one option. These stable tokens are parsed by CI and release automation.

  • bug - Bug fix; creates a patch release.
  • feature - Feature or stabilization work intended for the current beta minor line; creates a patch release before 1.0.
  • feature-minor - Real feature intended to advance the beta minor line; creates a minor release before 1.0.
  • breaking - Breaking beta change; creates a minor release before 1.0.
  • docs - Documentation-only change; no release.
  • refactor - Non-functional cleanup or refactor; no release.
  • test - Test-only change; no release.

How Has This Been Tested?

  • Unit Tests: pytest tests/test_...
  • Integration Tests: pytest -m integration
  • Manual Test: (Please describe)

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • I have checked my code and corrected any misspellings

Di3Z1E added 5 commits May 14, 2026 09:22
Add full chacha20-poly1305@openssh.com support to the crypto backend:
encrypt, decrypt_length, and decrypt_body methods using the SSH AEAD
construction (two-key split, Poly1305 tag over enc_length + enc_body).

Register the cipher in CipherSuite as the preferred encryption algorithm,
add AEAD_CIPHERS sentinel set, and fix the strict-KEX signal token from
the incorrect v01 suffix to the correct v00.
Wire chacha20-poly1305 into the sync transport: add key fields
(_chacha20_key_out/in), encrypt and decrypt through the backend methods,
and switch _cipher_block_sizes to treat chacha20 as block size 8.

Switch _packet_buffer from bytes to bytearray to eliminate O(n) copies
on buffer advance. Add PacketProfiler (SPINDLEX_PROFILE=1) for per-stage
build/encrypt/write timing.

Fix validate_packet_structure minimum size check to be AEAD-compatible
(minimum body 8 bytes instead of the previous MIN_PACKET_SIZE constant).
Implement the chacha20-poly1305 inbound packet path in AsyncTransport:
read enc_length (4B) → decrypt length → read enc_body + tag (16B) →
verify Poly1305 and decrypt body via the crypto backend.

Reset the outbound sequence number to 0 after sending NEWKEYS when
strict-KEX is active (Terrapin defense). Move the writer presence check
before packet build/encrypt so no work is done on an uninitialised transport.
Add _query_limits() to SFTPClient: after version negotiation, if the
server advertises limits@openssh.com, send SSH_FXP_EXTENDED and parse
the 4×uint64 reply to extract max_write_len. Store in _max_write_len
(defaults to 64 KB if the extension is absent or the call fails).

Update SFTPFile.write() and SFTPClient.put() to use _max_write_len
instead of the hardcoded SFTP_MAX_PACKET_SIZE constant. On OpenSSH
this raises the write chunk from 64 KB to 255 KB, reducing round trips
for a 1 MB upload from ~16 to ~4 and matching asyncssh throughput.

Track send_offset as a dedicated field on SFTPFile instead of
recomputing it from the queue on every write iteration.
@Di3Z1E Di3Z1E requested a review from adirothbuilds as a code owner May 16, 2026 05:00
@codecov-commenter

codecov-commenter commented May 16, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 70.10870% with 55 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
spindlex/transport/transport.py 62.61% 40 Missing ⚠️
spindlex/client/sftp_client.py 50.00% 13 Missing ⚠️
spindlex/hostkeys/storage.py 0.00% 1 Missing ⚠️
spindlex/transport/async_transport.py 93.75% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Di3Z1E added 3 commits May 16, 2026 08:06
Add chacha20-poly1305@openssh.com to benchmark_ciphers.py cipher profiles
and raise SFTP_CHUNK from 16 KB to 32 KB to match the new default.

Extend benchmark_production.py: add chacha20 to CIPHER_ALGORITHMS, add
MAC_ALGORITHMS list (hmac-sha2-256, hmac-sha2-512), add per-MAC
correctness checks and silent-fallback detection for nonexistent MACs,
and add mac parameter to _force_algos(). Remove diffie-hellman-group16-sha512
from KEX list as it is not implemented.
Comment thread tests/integration/test_chacha20_local.py Dismissed
Comment thread tests/integration/test_chacha20_local.py Dismissed
@Di3Z1E Di3Z1E merged commit 489fc76 into main May 16, 2026
37 of 47 checks passed
Di3Z1E added 6 commits May 16, 2026 14:20
Add docs/algorithms.md: full reference for all supported KEX, host key,
cipher, and MAC algorithms with preference order, notes, and an explicit
list of unsupported/excluded algorithms.

Replace the inline algorithm lists in security.md with a cross-reference
to the new page to avoid duplication. Add algorithms.md to the mkdocs nav.

Add .ruff_cache/ to .gitignore.
Reflect the 0.7.x release line: ChaCha20-Poly1305 as the preferred
cipher, limits@openssh.com SFTP write chunk negotiation (up to 255 KB),
and Terrapin strict-KEX. Update the beta warning, key features, benchmark
table, and security section accordingly.
Bump version to 0.7.0 in pyproject.toml, _version.py, and CITATION.cff.
Update CITATION date to 2026-05-16.

Update supported-version tables in SECURITY.md and docs/security.md
to mark 0.7.x as supported and 0.6.x as end-of-life.

Add 0.7.0 entry to docs/changelog.md covering ChaCha20-Poly1305,
limits@openssh.com SFTP negotiation, PacketProfiler, strict-KEX fix,
bytearray buffer, and all related fixes.

Update docs/index.md and docs/performance.md: replace stale AES-256-CTR
references with ChaCha20-Poly1305 as preferred cipher, document the
limits@openssh.com write-chunk negotiation, and add a PacketProfiler
section with usage example and sample output.
Ruff: fix import order in sftp_client.py, remove unused MIN_PACKET_SIZE
import from protocol/utils.py, sort imports and remove unused os import
in test_chacha20.py and test_chacha20_local.py, replace bare except with
except Exception.

Mypy: add assert narrowing for Optional[bytes] chacha20 key fields at
all call sites in transport.py and async_transport.py.

Bandit: suppress B110 (try/except/pass) on the non-fatal limits query
fallback in sftp_client.py._query_limits().

Ruff format: reformat five files to satisfy black-compatible style.
Replace all explicit references to competitor library names (asyncssh,
paramiko, AsyncSSH, Paramiko) in docs, changelog, meta, and issue
templates with generic alternatives such as "other SSH libraries" and
"other leading SSH libraries". Benchmark scripts are unaffected per
project policy.
@Di3Z1E Di3Z1E deleted the dev-0.7.0 branch May 16, 2026 17:53
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.

3 participants