Send with attestation and send to attestation, MVP use-case of attestation

TokenScript's attestation work enables one to send a token to another by email address / mobile without knowing the recipient Ethereum address. The following are copied from the note shared after TokenScript weekly meeting #11)

There is a similar protocol introducing a method to send tokens without the receiver having Ethereum address, aimed at solving onboarding issue:

To me, it seems LinkDrops model (“Send with attestation”) requires a secure channel to delivery, but no requirement for the receiver. The attestation protocol (“send to attestation”) doesn’t care the secure channels but requires the receiver have or can get an attestation.

Let's say the problem that needs to be solved here is to send someone a token without knowing his Ethereum address. There are only 2 methods that I can see.

By passing secrets

In LinkDrop model, it's assumed that there is a secure (confidential) way to deliver the link to the end-user and that opening the link in a browser does not leak the link. These assumptions I think is a bit overconfident since there are multiple points of potential leaks:

  • Android/iOS's leak through link handling.
  • If a link is sent by email, the Email software which may have a link redirector.
  • The web server that opens the link has to be secured, or the log leaks.

There are ways to amend it (e.g. send the LinkDrop link in 2 sections separately).

Generally speaking, it's not good to make a security assumption that is different than other IT systems. In many IT systems, link itself is not treated as secret.

By an identifier

Instead of "anyone who can see the link" this is directed to the recipient with an attestable identifier.

Alice (the sender) has to know something of Bob that bob can proof. This is a typical flow in other tokenisation cases (hence reuse value if made into a framework).

Sorry for putting this project on the shelf for 6 months. Victor, given that you prioritised this MVP I posted an updated version of the protocol following feedback from @tore and @jzaki & improved clarity. Would be great to get some feedback on the new description.

What are you planning to use for the second signature itself? What if we use the native signature we have in ethereum and just issue an additional special key pair for the privacy and the corresponding address becomes part of the CSR and later just “ecrecover" is enough to validate this second signature onchain. This address is never used as an actual address, just as a public key binding the ID

To what extent have we to support X.509? Is it actually signed by the trusted party or just saved onchain as a mapping address <> “subject of attestation s” through a privileged contract method? Where are you planning to use standard certificates?

  • Are certificates actually stored onchain? We could store them in something like IPFS to save on gas

  • Revocation. Do we have it? What if longterm keys of users are compromised / lost? Will we support revocation lists and all related functionality?

  • Your protocol is related to the field of Identity based cryptography. Have you considered more advanced schemes where the user is using ID as a public key? There are some interesting protocols using curves pairing and other techniques. They also need trusted parties, from what I know. But worth to check latest results in the field.

  • The trusted third-party server that issues the certificates is the most centric vulnerability. Are we planning to protect its keys that are used to sign the certificate somehow? Reissuing / expiring them, etc? This is also valid for the case if certificates aren’t actually signed but just stored in a smart contract (the privileged contract method called by the backend).

  • one time key p' has to be shared privately between A and B. So it’s not strictly sending money to an email, additional secret has to be securely delivered. This makes the protocol interactive. What are we going to use for sending this key? No way to encrypt this p’ as Bob doesn’t have any accounts/keys at that moment yet. Considering p’ is not enough by itself to redeem, maybe just over email is fine? And it makes some extra protection if the longterm key p is compromised.

  • Multiple use of the protocol, when many s1’, s2’,… (in cheques) and x1, x2, … (in redeems) are published onchain into the smart contract, partially reveals long term secret p to an observing attacker. This information accumulated can be used to find p faster than direct discrete logarithm problem.

  • Vulnerability issue: the long-term privacy key p of a user is immediately compromised to every party who sent a payment to this user after the payment was redeemed. This is because x is published onchain and p’ is generated by the party. So after a first redeemed payment we can consider the scheme secure only because of the validation of the main ethereum address (comparison of the transaction sender and the address certified for the user). All manipulations with s’, p’ and x become useless. Maybe some variation that can prove knowledge of x without publishing it in the tx is possible, good direction to think.

I assume by the second signature you mean the one produced with privacy key 𝑝. You propose that instead of signing with 𝑝, the user includes the identifier of 𝑝 (as an Ethereum address) in the attestation, therefore signs once with the Ethereum account key.

The reason is that this topic is part of the work of attestation framework. Attestation is a statement by the attestor that he attests to something. An attestor can't attest to something that he doesn't know. For example, in order to attest to the identifier such as Bob's email address, the attestor sends a verification code to that email address and verifies it on a webpage, hence it knows the user has that email address. †

In your alternative version, the attestation issuer doesn't 𝑘𝑛𝑜𝑤 that the user has the privacy key 𝑝, merely that the user claimed so in their CSR. In this specific protocol, it doesn't open much attack surface, since the smart contract also need to verify ownership of 𝑝, the user won't be able to use the attestation if he doesn't have 𝑝. Therefore, in order to steal the money, an attack resorts to fooling the user to generate a CSR with the attacker's identifier of 𝑝 instead of the user. It can be argued that such an attack requires control of the user's mobile device and hard to do.

But such an alternative breaks the semantic of the word "attestation", and now developers think "an attestation may have something that the attestor attests to 𝑝𝑙𝑢𝑠 something that the attestor merely received without attesting to", and then they no longer consider an attestation as an attestation, but a signed message whose purpose and use must be understood in the context of the protocol, which diminishing the reuse value of attestations (especially the reusability between smart-contracts - think for example non-U.S. citizenship attestation is useful in all ICO smart contracts, not protocol-specific). This already happened in domain certificates, where organisation name (o) is merely acknowledged in CSR and not verified, which later lead to the (re)invention of EV domain certificate, where every attribute signed by the issuer is verified.

By the way, when you say "on-chain" do you mean "in a smart contract"?

† One way to assert that knowledge is simply passing as is 𝑝 to the attestor, since the attestor already has the power of facking an attestation and stealing the money if gets the cheque, giving away 𝑝 as-is is not increasing the power of the attestor. But to prevent stolen mobile phones reveal 𝑝, it has to be stored in the mobile phone's strongbox, which can't be revealed in any way, hence not able to be passed to the attestor. The other method is to do an authentication challenge separately, outside of the CSR.

There are 4 goals when we based our work on X.509:

  • that code works with X.509 (e.g. bouncy castle) is able to work with attestations without overhaul.

  • that existing X.509 (domain certificate) can be used as an attestation to an extent. In X.509 by some convention, the subject of a certificate is typically attested to (e.g., while the rest is merely acknowledged. Re-use that part.

  • that the security flaws found and fixed remain fixed with attestation. e.g. to prevent carefully crafting a fake signature with a signing algorithm that is already compromised, SignedInfo must contain the signing algorithm.

  • that extensibility is achieved following the longevity of X.509 (this is mostly the courtesy of ASN.1 actually, not X.509 per se. If we can make sure all components of a system is controlled by a single entity like Google or Facebook, we can just invent new things or reuse Protocol Buffer, but decentralized systems are bound to be upgraded at different pace and some will never upgrade, where extensibility of ASN.1 is useful.

An attestation, if used in a transaction, a version or a part of it would be left on-chain (the part smart contract reads). Normal attestations might float on IPFS if properly secured, but why not keep it in the user's wallet if no one but its key-holder is able to use it? One argument is so that the user doesn't have to keep a wallet (that keeps the attestations). I'm not yet sure if blockchain use-cases would grow a lot if users are spared of using wallets.

On the other hand, most attestations require additional keys thanks to the lifecycle difference, use-case difference and security requirements (the use of mobile strongbox). So not having to store attestations doesn't remove much burden from the users as they still need to manage their corresponding keys..

Some attestations, like Cheque, for example, is a special attestation that allows redeeming money, can't stay on IPFS. If stored on IPFS, the attestor (attestation issuing "authority") would be given the power of stealing the money promised in it (the attestor already have the power to front-run the user after the user sends a redeeming transaction, but putting it on IPFS expands the power, making them more likely targeted).

Is the job of the set of EIPs published by my colleague @James-Sangalli 2 years ago. Yes it will be needed to make the protocol complete.

Yes, interested.

We don't want to reveal the user's pre-hashed identifier so you can't rid the confidentiality requirement on the attestor, therefore in most practical cases we can't rid the attestor altogether and have smart contract doing its role. In this protocol, email address / SMS number. In another case like non-US-citizenship attestation, it would reveal the addresses of non-US-citizens. Tore and I had a paper on this 2018.

You are right that if the one-time key 𝑝' is exposed, a malicious party still needs Bob's attestation and its privacy key 𝑝 to redeem that money to an address not owned by Bob. In a way, 𝑝' works like the public key of 𝑝 (not directly but through the attestation).

This is designed to lower the requirement of secure communication between A and B. The protocol is intended to be used without a secure communication channel (like TLS) but merely a confidential one.

The difference is

  • a secure communication channel has only A and B
  • a confidential channel has eavesdroppers G and F (Gmail and Facebook), both with a confidentiality obligation of "knowing but not telling", and are required not to cooperate with the attestation issuer.

Therefore it's not interactive.

Check my first post under this thread for a comparison.

It is true that security might be weaker than the standard Discrete Log Problem. Basically the security reduces to what is known as the One-more Discrete Log Problem (a discussion of these types of assumptions can be found here Which is probably a stronger assumption (meaning that it is probably easier to solve than the “normal” discrete log problem). However that does not necessarily mean it is easy. It is a commonly used assumption in cryptographic work and generally trusted to be secure, although a pure Discrete Log assumption is of course preferred.

Excellent point! This is an issue if the sender is also a node on the blockchain. As you suggest this can be fixed with a non-interactive ZK proof. For this specific case, what we will want to prove is knowledge of the exponent 𝑥 s.t. 𝑠ˣ=𝑠'. That is, proving knowledge of the discrete log. This can be achieved using only two exponentiations with the Fiat-Shamir protocol for the Schnorr proof.

After making a reference implementation here I have found a couple of things we should probably consider.

  1. Using a hash function it should be possible to have Bob derive a secret directly from his private Ethereum key using a hash function (so he does not need to remember anything new).
  2. Bob's request to redeem MUST be signed to avoid main-in-the-middle and mix-and-match issues. For the second thing I have already updated the file.

Hey @jot2re , I saw Victor's post on devcon, and just caught up on the theory here :smiley:

In the "Attestation" section, the first steps prove Bob is in possession of some private p. Then in step 4, the signing of the CSR proves that Bob (owner of i) is in possession of a private key for the public Ethereum address. The attestor can't check that p is the same as the private key to the Ethereum address (although the attestee incentives imply it should be)...

Would it be possible for an attacker to calculate a value for p2 s.t. H(i2)^p2 = s, (p2 = log(s)/log(H(i2)))? Submitting a proof using this p2 will yield the same s, a different proof q (using H(i2), but signing with a different private key for the attacker's ethereum address. The attacker is now in possession of an attestation for subject s tied to their Ethereum address.

My understanding of modulo in the discrete log problem is that it's hard to solve for p specifically, but if we only need a solution not the solution, then this seems possible as described above (I think it's finding the first solution in the range?).

In the same way, could an attacker redeem any cheque looking to solve s'=s^x, to their attested subject s2, using x = log(s')/log(s2)? The malicious-redeemer calculates everything from the start with their s2 (and their calculated x) to satisfy the smart contract checks.

Maybe I've missed something and just need a coffee this windy Sunday morning :stuck_out_tongue:

Hi @jzaki. Thanks for having a look at this! So first of all, if the adversary is able to solve the discrete log problem then he can trivially break the entire protocol exactly as you say. Since in this can he can simply compute a fitting value of p2 trivially. I should note that there is only a single correct solution to the discrete log problem in the same manner as the normal logarithm problem. Furthermore it is not needed that p is the same as his Ethereum private key (ideally it shouldn't be, but instead be derived from his private key deterministically). However, he might have some side information, like he might know Bob's email and thus know H(i). However this does not give him enough information, since H(i) is just the base of the discrete log problem he is trying to solve. But maybe I am misunderstanding what you mean? I try to following your argument but I cannot see how a bad guy can make an attestation to p2 based on s=H(i)^p without being able to compute p2=log_{H(i2)}(s). The same goes for computing x such that s'=s2^x. Please let me know if I am misunderstanding what you mean? :slight_smile:

1 Like

However, he might have some side information, like he might know Bob's email and thus know H(i) .

Yes, this is the case for each sender of a redeemed cheque, I think this was also noted at the end of the write-up too. Cheques are anonymous until attempted to be redeemed, then any previous sender can spot it when a redeeming tx is sent to be processed.

I should not(e) that there is only a single correct solution to the discrete log problem in the same manner as the normal logarithm problem

I thought wrapping (due to the mod chosen) means the same output can occur with different inputs. But I trust your judgement over mine in its use here.

When it comes to repeated multiplication of large numbers (2^256) wrapping via overflow is also guaranteed too. Maybe I missed an implementation detail captured elsewhere for how this will work on-chain (limited computation vs using precompiles for EC ops).

Looking forward to seeing it all in action :muscle:

Kudo to @jzaki for 1) bumping up the correct old post instead of starting a new one and 2) taking time to peer review the protocol.

Digressing a bit, I think the devcon case demonstrated a repeatedly occurring scenario in business-case experiments that Sunil/Jameses and I had during 16~17 (attestation on an identifier -> identifier attestation on a key). That's one of the reasons of our research work on attested transactions on Ethereum right after leaving the bank in 2018. (Why research -> since Eth complicated the matter by having the chain public)

2) taking time to peer review the protocol

Hahaha, I wouldn't give it such a high-title, more of a Sunday morning read :stuck_out_tongue:

The large on-chain exponent calculations have me curious, but I've never measured gas used for things. I thought keccak256 and zksnarkverify can work on-chain by using precompiled contracts. But I trust you've thought it through :muscle:

Me too. I'm taking the naïve view that Elliptic Curve discrete logarithm problem having the same properties as discrete logarithm problem so the protocol should be implementable in ECC in its entirety, and I used logarithm syntax to represent elliptic curve "multiplication" in all documents I wrote; doing so doesn't mean I intend the actual exponent calculation to happen. The reason I remain curious about large on-chain exponent calculations is that there might be the need to involve traditional attestation issuers (like this one Victor proposed) but I wasn't expecting it as a condition for this protocol to work.

Yes, I agree with this. It is not the cheapest protocol computationally-wise. I believe we already discussed that at some previous meetings and as Weiwu says, this can all be based on ECC. So hopefully there will be some way of leveraging the ECC operations on the smart contract API to implement this :wink: But in all cases, this is a first attempt of achieving something like this so for a start it is not bad, even if it requires some point multiplications (equivalent to multiplicative group exponentiations).

Okay, okay, to be pedantic; there are more solutions. But none less than the value of the modules. If a solutions to the DL problem is x with x<modulus then x+modulus-1 will also be a solutions (if we work modulo a safe prime (a prime where prime-1/2 is also a prime)). I ignored these since we ar always working modulo a certain number so for practical purposes they become irrelevant here. But you do raise the point that wrapping modulo this prime is important for security purposes.