You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current challenge hash concatenates the hex-encoded text of each point before hashing:
e = SHA256(hex(R1) || hex(R2) || hex(A) || hex(C'))
Each uncompressed point is 65 bytes -> 130 lowercase hex characters, encoded as UTF-8 bytes before the SHA256. The lengths are fixed so there's no boundary ambiguity, but there's an encoding pipeline that cross-language implementations have to get right in full.
We could use a cleaner form, following BIP-340 conventions:
e = SHA256(b"Cashu_DLEQ_E_v1" || R1 || R2 || A || C')
Notes
Simpler implementation: Points are raw uncompressed SEC1 bytes (65 bytes each). The domain tag is 15 UTF-8 bytes. No intermediate encodings required.
This doesn't close any known attack: the current encoding is unambiguous. The motivation is implementation correctness: wrong hex case, wrong text encoding, or a missing encode step can all silently produce a different hash.
Migration: this is a breaking change. All existing DLEQ proofs would fail under the new hash scheme.
Implementations would need to try the new hash first and fall back to the legacy function during a transition window while tokens cycle out of circulation.
The current challenge hash concatenates the hex-encoded text of each point before hashing:
Each uncompressed point is 65 bytes -> 130 lowercase hex characters, encoded as UTF-8 bytes before the SHA256. The lengths are fixed so there's no boundary ambiguity, but there's an encoding pipeline that cross-language implementations have to get right in full.
We could use a cleaner form, following BIP-340 conventions:
Notes
Simpler implementation: Points are raw uncompressed SEC1 bytes (65 bytes each). The domain tag is 15 UTF-8 bytes. No intermediate encodings required.
This doesn't close any known attack: the current encoding is unambiguous. The motivation is implementation correctness: wrong hex case, wrong text encoding, or a missing encode step can all silently produce a different hash.
Migration: this is a breaking change. All existing DLEQ proofs would fail under the new hash scheme.
Implementations would need to try the new hash first and fall back to the legacy function during a transition window while tokens cycle out of circulation.
Suggest this follows feat(nut12): deterministic DLEQ nonce derivation #368 once that settles: the nonce change was free, this one needs a coordinated migration