Skip to content

Deprecation warning for the Kyber classes #14

Closed

Description

@Zikithezikit

From #3: warn the first time someone uses a Kyber* class, once per process, and change nothing else.

  • Any Kyber* entry point (constructor, from_keys, static encapsulate/decapsulate) warns on first use. Importing doesn't warn
  • One warning per process total, across all three classes
  • The message says Kyber and ML-KEM aren't interoperable (both sides need to switch) and links the migration guide
  • Test it in a subprocess: use the classes many times, count exactly one warning; golden vectors still pass

Use a quiet DeprecationWarning for now: a KyberDeprecationWarning subclass, with stacklevel set so it points at the caller's code. Python only shows it by default when it comes from __main__, and that's fine for this release. The README will say it clearly.

Done when: the subprocess test passes and output is unchanged.

Depends on: #13. Plan: WP-6.

Part of #3.

Activity

  1. added this to the 2.0.0 milestone on Oct 29, 2026
  2. Zikithezikit commented on Oct 30, 2026

    @Zikithezikit
    OwnerAuthor

    Handoff for whoever picks this up (#13 is merged; dev-v2 has everything it needs).

    Where the entry points are, all in python/pykyber/_kyber.py: for each of Kyber512, Kyber768 and Kyber1024, __new__, from_keys, and the static encapsulate and decapsulate. The methods on the returned Keypair come after a constructor or from_keys call that already warned, so they need nothing. Do not touch python/pykyber/_mlkem.py: ML-KEM must never warn, and there is no shared base class with the Kyber classes.

    Things that will bite:

    • Python hides DeprecationWarning unless it is attributed to __main__, and the default per-location registry can swallow repeats. Guard "once per process" with your own module-level flag (take a lock so two threads cannot both warn) instead of relying on the filter, and in the subprocess test run with -W always::DeprecationWarning or -W default so you see what is really emitted. Also test that the warning is silent by default for an imported library and that importing pykyber alone emits nothing.
    • stacklevel has to land on the user's call, not on _kyber.py. The depth differs between __new__, the classmethod from_keys and the static methods if you route them through a helper; check it with a test that reads warning.filename.
    • The existing tests (test_kyber.py, test_legacy_vectors.py, parts of test_mlkem.py) use Kyber classes in-process and will now see the warning. Check pytest does not turn warnings into errors anywhere (CI, pyproject) and do not edit those tests to hide it. Output must stay byte-identical; the golden vectors are the proof.
    • The message links the migration guide, which Docs: point everything at ML-KEM and write a migration guide #15 writes. Use https://github.com/Zikithezikit/pykyber/blob/main/docs/migration.md and tell Docs: point everything at ML-KEM and write a migration guide #15 in the PR that this exact path must exist.
    • Export KyberDeprecationWarning in __all__. It is a warning, not an error, so it does not belong in _error.py; a new small module is fine.

    Not in scope: README and docs (that is #15), version bump, any change to the Kyber behavior.

  3. Zikithezikit commented on Oct 30, 2026

    @Zikithezikit
    OwnerAuthor

    Done in #38 (rebase-merged into dev-v2 as a666d76 and 6883dd8). First use of any Kyber512/768/1024 entry point emits one KyberDeprecationWarning per process; importing and ML_KEM_* never warn; Kyber output is unchanged (golden vectors pass untouched). The subprocess tests are in python/tests/test_kyber_deprecation.py.

    The warning message links https://github.com/Zikithezikit/pykyber/blob/main/docs/migration.md, so #15 has to create exactly docs/migration.md.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestlegacy-kyberRound-3 Kyber classes kept for compatibility

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions