Skip to content

Instantly share code, notes, and snippets.

@kayabaNerve
Last active November 3, 2022 00:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kayabaNerve/8066c13f1fe1573286ba7a2fd79f6100 to your computer and use it in GitHub Desktop.
Save kayabaNerve/8066c13f1fe1573286ba7a2fd79f6100 to your computer and use it in GitHub Desktop.
[Deprecated] Monero - Guaranteed Addresses

This has been deprecated for Featured Addresses.

Guaranteed Addresses

Monero payments are not guaranteed to be spendable, when individual transactions are scanned. Only when the entire chain is scanned will you learn if an output has conflicts, and only with the private spend key can you see if one of those conflicts has been spent, already having burnt all potentially usable outputs. This makes view-only scanning of the chain insecure, under the standing policy of "credit difference", as the wallet will credit the difference even if the funds are already burnt.

It should be noted wallet2 will stop crediting the difference if it knows the key image was used, as it should, yet it will continually credit if view-only, as it'll never learn when key images are used (unless imported, which may break a desired privacy model). Unfortunately, this is not an issue with a simple fix. Solely crediting the initial transfer potentially leaves funds on the table, though is the most secure (assuming view keys aren't published to untrusted parties, enabling the "extrapolated burning bug"). These funds would be burnt when a transaction occurs. If the funds have already been burnt, these funds would still be reported as incoming transfers when they are not.

Acknowledging the official flow as requiring key images be kept up to date is the current policy, yet there is a timing attack present unless the view-only wallet is the only wallet watching, which is also the wallet who publishes the spending transaction (as then it can cross off the key images BEFORE they appear on the network). If there are multiple wallets watching, they'd all need to have key images imported BEFORE any transactions out are made, continuing the pain the burning bug poses.

Between this reliance on full context, and presented insecurity to view-only wallets, not to mention the complications to best handle the burning bug, a new address format is proposed. This new address format is not actually a new address, yet rather an additional option applied to all existing address types.

Identification

The new address reuses the existing address bytes, in order to not double the amount of address bytes in use, yet with the top bit set. This means parsing of the address is possible by clearing the top bit, which no address bytes currently use, and then tracking if the address is a Guaranteed Address by address byte & flag == flag.

Sending

The shared key, Hs(8raG || o), is re-defined as Hs(uniqueness || 8raG || o). uniqueness is defined as H("uniqueness" || {input.uniqueness}), where {input.uniqueness} is the sorted set of unique factors present in each input. For miner transactions, this would be the height, in its VarInt encoding. For non-miner transactions, this would be their key images.

Vectors

To be provided after sufficient consensus is reached on this as a design.

Usages

This removes the burning bug, enabling much simpler wallet code, while also allowing contextless wallet scanning. It makes view-only wallets secure, without needing to be kept up to date on spent key images, and removes the extrapolated burning bug, enabling organizations to post their view keys without putting their users at risk of other users.

This will have notable benefits when integrating Monero into decentralized protocols, while also enabling more secure payment processing. Those two subsections of Monero software are the intended userbase for this.

Implementation

This is being proposed now, for RingCT Monero. This is an optional extension to the protocol, completely within the realm of wallets, which produces no on-chain differences. Accordingly, this can be implemented by any party, at any time, so long as they acknowledge they're potentially cutting themselves off from a large section of Monero.

Two phases of implementatation are acknowledged:

  • Sending. Wallets which can be told to send to a Guaranteed Address, doing so in the expected way.
  • Receiving. Wallets which can generate Guaranteed Addresses and successfully receive to them.

Wallets SHOULD implement sending, with the understanding it may be dropped in future releases and no guarantees on its long term support. This enables experimentation under it without being stuck with its burden, while enabling parties to use this protocol to receive funds without concern over how no wallets support it. With sufficient wallet support, parties have it as a legitimate option, and with their usage is inclusion justified. This is intended to be a no-cost way for wallets to give this new address format a legitimate chance at usage, enabling evaluation of its actual usage.

Wallets SHOULD NOT implement receiving. Doing so would be a commitment to this format for life, and should only be done if this format achieves notable adoption/benefit. If decentralized protocols, or payment-oriented software, want to implement it, that is for them to decide within their own scope. This policy should be updated depending on adoption and utility.

This is not being proposed for any form of integration into the official wallet2 until we can review real world usage, which is unfortunately predicated on someone taking the first step. Hence the appeal to wallets to enable parties to do so.

Initial implementation

A fork of Monero, post hard-fork tagged release, implementing this as a reference (while guaranteeing fund accessibility until the next hard fork, for anyone who does decide to use this), and a patch file is expected to be provided before implementation occurs. This patch file would aim to make it trivial for community wallets to provide support.

Notes

  • The extrapolated burning bug only makes economic sense when standard/integrated addresses are used (or subaddresses which still use extra to determine payout, an unexpected use case of them). This scheme is also defined for subaddresses to provide a fix for the classical burning bug as well though, not to mention be comprehensive.

  • Seraphis contains a similar fix, yet is expected to be 1-2 years out. There are parties needing this now, and others who may benefit from it now.

  • I am personally planning to deploy a decentralized protocol based on this modified definition, making myself one of those parties. This document is an attempt to provide a formalization enabling non-fragmented usage by any party. I am in discussions with a wallet2-based wallet already to implement this scheme internally for my work, already offering a step towards implementation. Exposing it as a proper address potentially offers further security to view-only processes, while the internal formulas here are an attempt to prevent fragmentation among wallet software and promote a healthier ecosystem.

Topics for discussion:

  • Is using the top bit too pretentious of this document, or simply the best way to implement this?
  • Which wallets would be willing to support this?
  • Off-chain privacy if an organization uses such an address, identifying they're using a certain wallet for receiving.

References:

@kayabaNerve
Copy link
Author

kayabaNerve commented Jun 28, 2022

The uniqueness factor is meant to be for the transaction, not for the output. It relies on the shared key as a whole being Hs(uniqueness || 8raG || o) to guarantee per-output uniqueness. Including || o inside the uniqueness calculation would require two hashes per output scan, whereas this is +1 per transaction.

Domain separating miner inputs from non-miner inputs is interesting. I left that to the fact a VarInt is a few bytes and a single key image is 32 to avoid the conflicts there...

EDIT: This was in response to a comment which apparently was deleted.

@kayabaNerve
Copy link
Author

Addresses are explicitly defined as a VarInt for the address type bit. This proposal conflicts with that. While JAMTIS will occur before address types hit 128, potentially meaning we can revoke that definition and use its bit, any existing software using this definition may conflict. If the next byte is 0, it'll decode to the legitimate address byte, just with an invalid length. This seems to be too much of a conflict to be encouraged.

The two alternatives are:

  • Per-network bit masks.
  • Duplicating address bytes as whole.

I'm in favor of the former and will review potential bits later.

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