rgb-archive / spec

[OLD!] RGB Protocol specifications for Bitcoin-based digital assets
https://rgb-org.github.io/
148 stars 26 forks source link

Design proper multi-asset proof specs #87

Closed dr-orlovsky closed 4 years ago

dr-orlovsky commented 5 years ago

Each proof can cover multiple asset transfers issued by a multiple contract. We need to ensure that this part is covered through spec. We also need to design how asset_id is defined: it needs to contain hash of the contract + some id of the asset within that contract.

dr-orlovsky commented 5 years ago

Background: each asset is issued by some contract. It may be reissued multiple times, but the original issuing contract remains always the same, we will simply name it "issuing contract". An issuing contract may issue one or more assets.

This means that in order to uniqually define assets we need to use information from both issuing contract and some index of the issued asset within that contract (it will also require to add some asset indexing capabilities into the issuing contracts of future blueprint types, like proof-of-burn issuing).

Thus, for asset_id we have the following options (let contract_id be the id/hash of the issuing contract and index an index of the asset within that contract and # be some hash function):

Explicit sheme provides more readability, implicit – more privacy, while the mixed one makes a tradeoff between them. Since the proofs are already private pieces of data, I would prefer an explicit scheme. Other thoughts?

inaltoasinistra commented 5 years ago

I don't think readability is valuable in this situation. contract_id is an hash, so it is not human readable. Wallets softwares will show readable labels, they could show indexes or other information useful for the user. The advantages of the implicit scheme are fixed size and a yet defined type to represent asset ids.

dr-orlovsky commented 5 years ago

From the planned Spectrum DEX functionality, required for an efficient asset routing, it follows that RGB-enabled LN nodes would have to announce the list of assets (i.e. asset ids) they can buy/sell – with corresponding bid and ask prices. Since we'd like to increase the privacy, we need these asset ids to be "obscured", i.e. not easily tracked down to the specific asset/contract – unless for those who has the source of the asset issuing contract. This leaves us with just a single option:

asset_id needs to be a hash of a public key; public keys for each asset need to be listed in the issuance contract; these keys should be derived from some entropy (private key) produced by the issuer during issuing contract creation; this private key can be dropped after

Why we could not just rely on #(contract_id || index)? Because contract_id is much more public than the contract data, and it will be quite easy to construct "rainbow tables" with contract_ids joined by different indexes and track the asset ids down to the issuing contracts.

dr-orlovsky commented 5 years ago

Second thought: if we just use hash of an arbitrary public key as an assetId, there will be cases of creation of assets with the same id by different contracts – as an attack vector. So probably this scheme can be upgraded with the following:

asset_id = SHA256(SHA256(contract_id || bind_to_utxo || asset_no) * G)

I.e. we use the actual hash of the serialized contract + UTXO to which the contract is committed to + asset number within that contract (fin order to support multi-asset issuing contracts) to deterministically generate EC private key; than we take a hash of the corresponding public key and use id as an asset_id.

This protects from issuing multiple assets under the same id and allows anybody to verify the correspondence of the given asset_id to the given contract_id.

dr-orlovsky commented 5 years ago

In order to optimize the size of the proofs, I propose the following algorithm for referencing different assets within the proof:

  1. Provide a list of all used asset_ids in the proof in an arbitrary order (this required in order to reduce proof predictability).
  2. Organize the asset transfer information inside the proof as an array of arrays of tuples: [ [(amoun1, dst1), (amount2, dst2), ...], [...], ... ], where each subarray with index no contains asset transfer tuples for a given asset_id with the same index no in the assets list from pt.1 above.
dr-orlovsky commented 5 years ago

asset_id = SHA256(SHA256(contract_id || bind_to_utxo || asset_no) * G)

This, in fact, can be further reduced to

asset_id = RIPMD160(SHA256(contract_id || bind_to_utxo || asset_no))

also giving smaller size for the asset_id, and making it indistinguishable from Bitcoin addresses

dr-orlovsky commented 4 years ago

After discussion with @giacomozucco it was decided to stick to scheme from the last comment for the version 0.5.0