Both signatures have to pass.
The signature is ML-DSA-65 concatenated with Ed25519. Checking one half and skipping the other is not this construction. Edit the text after signing, or flip a byte, and the check should fail. If the worry is a shortcut in the lattice rather than a quantum computer, use the hash signature.
Try it
- 01
Sign the text.
The first time also generates the key. The public key is 1,984 bytes: 1,952 of ML-DSA-65, then 32 of Ed25519.
- 02
Change the text and check it.
The signature is not updated. Check uses the signature you already have against whatever is in the box now.
- 03
Or damage the signature itself.
The last byte is the Ed25519 half. The first byte is the ML-DSA half. Either change is enough to reject.
Same call in Python
from qrclib.hybrid import generate_sign_keys, sign, verify keys = generate_sign_keys() signature = sign(keys.secret_key, message) assert verify(keys.public_key, message, signature) assert not verify(keys.public_key, message + b" ", signature)