Skip to content

blind: add support of extra data for range proofs - #303

Open
juja256 wants to merge 1 commit into
ElementsProject:masterfrom
juja256:master
Open

juja256 wants to merge 1 commit into
ElementsProject:masterfrom
juja256:master

Conversation

@juja256

@juja256 juja256 commented Oct 27, 2026 •

Copy link
Copy Markdown

Elements wallets embed a 64-byte message in each output's range proof (asset id ‖ asset blinding factor), which the receiver recovers by rewinding the proof. libsecp256k1-zkp accepts a much longer message, up to 128·(rings − 1) bytes, which is at least 3200 bytes with TxOut's range proof parameters. But RangeProofMessage could only carry the 64 bytes, and TxOut::unblind discarded anything after them.

This PR lets a sender embed extra data after the 64 bytes and lets the receiver read it back. One use is protocol data meant only for the holder of the output's blinding key, e.g. confidential covenants.

Changes

  • RangeProofMessage::with_extra_data(Vec<u8>) and extra_data().to_vec() returns the full message; to_byte_array() still returns only the 64-byte asset part.
  • Value::blind and Value::blind_with_shared_secret embed the full message.
  • New TxOut::unblind_with_message, which returns the output's secrets together with the recovered message. TxOut::unblind now calls it.

Compatibility

  • No breaking changes: RangeProofMessage's fields were already private, and new() is unchanged.
  • Without extra data the embedded message is still the same 64 bytes, so range proofs are byte-identical to before and unblind returns the same result.
  • Receivers that ignore extra data, including unblind, still unblind outputs that carry it.

Notes

  • A rewound message is zero-padded up to the proof's capacity, so the original length of the extra data can't be recovered. This is documented on extra_data(); callers that need the exact length must encode it in the data.
  • Blinding fails if the message exceeds the proof's capacity: e.g. more than 3136 bytes of extra data.

AI usage disclosure

The code of PR was mainly generated by Claude Opus 5.5 with Claude Code harness, but was carefully reviewed by a human.

@apoelstra

Copy link
Copy Markdown
Member

Is this LLM-generated? Can you mention what model/harness/provider you used?

This may be blocked on updating rust-secp256k1-zkp; there are some fairly serious issues with the rangeproof API that we'll fix in the next update.

@juja256

juja256 commented Oct 27, 2026

Copy link
Copy Markdown
Author

Yes, added AI disclosure.
Btw, this PR will be very useful for building confidential covenants: e.g. piggyback some auxiliary confidential data in the private rangeproof channel to the recipient.

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.

2 participants