From 4b9820b18e916f892ac842f7a2090a83fcd49e9a Mon Sep 17 00:00:00 2001 From: disqualifier Date: Mon, 6 Jul 2026 20:10:32 -0400 Subject: [PATCH] fix: keep the concrete type in the set-members fingerprint marker The 6d370a4 determinism rewrite collapsed the set-value marker from f'{type(value).__name__}:members' to a bare '\x00set:members', so a set value and a frozenset value with the same members fingerprinted identically - a fix-introduced collision that contradicts the same commit's collision-resistance claim. Restore the concrete type in the marker (keeping the \x00 prefix so it stays uncollidable with a user string key). Determinism across processes is unaffected. Signed-off-by: disqualifier --- src/envelope_crypto/envelope_crypto.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/envelope_crypto/envelope_crypto.py b/src/envelope_crypto/envelope_crypto.py index ea76224..521c69f 100644 --- a/src/envelope_crypto/envelope_crypto.py +++ b/src/envelope_crypto/envelope_crypto.py @@ -681,7 +681,9 @@ def _fingerprint_normalize(value: Any) -> Any: if isinstance(value, (set, frozenset)): members = [_fingerprint_normalize(item) for item in value] members.sort(key=lambda item: json.dumps(item, sort_keys=True, default=_fingerprint_default)) - return {"\x00set:members": members} + # keep the concrete type in the marker so a set value and a frozenset value with the + # same members stay distinct; the \x00 prefix keeps it uncollidable with a user str key + return {f"\x00{type(value).__name__}:members": members} if isinstance(value, (list, tuple)): return [_fingerprint_normalize(item) for item in value] return value