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
Spec for raiden-network/raiden#7071
When making a transfer, after validations pass, we need to reveal the secret only to target. Usually (fallback case), this is done by target sending a message to initiator requesting the secret, initiator doing the validation on its side and then revealing the secret to target directly, which then is able to proceed with unlocking. There's a way to do that without requiring this slower messaging exchange, by using ECIES to encrypt the secret and the information needed for its validation with target's public key. The downside is that this puts the responsibility of validating these information on the target, and the initiator doesn't have the ability to cancel this transfer by forgetting the secret before revealing anymore. But we never implemented features which would require this anyway, and the optimisation is more important ATM.
Spec
This is only possible if all nodes in path support immutableMetadata capability #343 ; we should at least check partner and target for that capability.
In case it's possible, when creating a transfer, initiator can encrypt the secret to target:
It should fetch target's pubkey from its address_metadata (public key is recoverable from the displayname being the signature of the user_id).
With it, it uses ECIES (ecies/js, ecies/py) to encrypt an object containing secret and the metadata needed for validation
this object must be in the format: { "secret": HexString, "amount": NumericString, "payment_identifier": NumericString }
in pseudo-code: LockedTransfer.metadata.secret = hex(encrypt(target.pubkey, json.dumps({ secret, amount, payment_identifier })))
When receiving a transfer, target may check metadata.secret is present and try to decrypt and validate it:
metadata.secret should be an hex string, to be decrypted with its PrivateKey
The resulting string must be parseable as a JSON object in the above format
in pseudo-code: obj = json.loads(decrypt(privateKey, transfer.metadata.secret))
obj.secret must hash to the transfer's secrethash
obj.amount must be less than or equal received amount
obj.payment_identifier must be equal to transfer's payment_identifier
If the above validations pass, we use secret as this transfer's secret and skip requesting it to initiator and start the SecretReveal/unlock phase; otherwise, we proceed with the previous/fallback behavior
Target may skip creating an RTC channel with initiator if secret is present in the transfer.
Conclusion
This change depends on immutableMetadata capability, but it'll gracefully fall back to behavior compatible with 2.0/Bespin in case it isn't possible, so it's fully backwards compatible.
This is an optimisation to avoid target needing to message initiator, which usually doesn't have an RTC channel established, and would allow RTC channels to be established only between partners, reducing the attack surface and speeding the transfer times since first transfer to a new target.
Abstract
Spec for raiden-network/raiden#7071
When making a transfer, after validations pass, we need to reveal the secret only to target. Usually (fallback case), this is done by target sending a message to initiator requesting the secret, initiator doing the validation on its side and then revealing the secret to target directly, which then is able to proceed with unlocking. There's a way to do that without requiring this slower messaging exchange, by using ECIES to encrypt the secret and the information needed for its validation with target's public key. The downside is that this puts the responsibility of validating these information on the target, and the initiator doesn't have the ability to cancel this transfer by forgetting the secret before revealing anymore. But we never implemented features which would require this anyway, and the optimisation is more important ATM.
Spec
address_metadata
(public key is recoverable from thedisplayname
being the signature of theuser_id
).{ "secret": HexString, "amount": NumericString, "payment_identifier": NumericString }
LockedTransfer.metadata.secret = hex(encrypt(target.pubkey, json.dumps({ secret, amount, payment_identifier })))
metadata.secret
is present and try to decrypt and validate it:metadata.secret
should be an hex string, to be decrypted with its PrivateKeyobj = json.loads(decrypt(privateKey, transfer.metadata.secret))
obj.secret
must hash to the transfer'ssecrethash
obj.amount
must be less than or equal received amountobj.payment_identifier
must be equal to transfer'spayment_identifier
secret
as this transfer's secret and skip requesting it toinitiator
and start theSecretReveal
/unlock phase; otherwise, we proceed with the previous/fallback behaviorsecret
is present in the transfer.Conclusion
This change depends on
immutableMetadata
capability, but it'll gracefully fall back to behavior compatible with 2.0/Bespin in case it isn't possible, so it's fully backwards compatible.This is an optimisation to avoid target needing to message initiator, which usually doesn't have an RTC channel established, and would allow RTC channels to be established only between partners, reducing the attack surface and speeding the transfer times since first transfer to a new target.
This also fixes raiden-network/raiden#473
The text was updated successfully, but these errors were encountered: