Question regarding ed25519verify and if it's possible to invert it

Opcode ed25519verify allows you to input some data A, a signature B and the public key C. It will then return 1 if the private key to C was used in B to sign A.

I’ve been looking into the Bitcoin-Monero atomic swap protocol. It requires the use of something called adaptor signatures. I’m not a cryptographer, this is mostly above my head, but I wrote about it here: Discussion & Feedback on adapting Bitcoin<->Monero atomic swap protocol for Algorand <-> Monero · Issue #92 · algorandfoundation/ARCs · GitHub. I suggested a proposal but it requires the ability to do the following: sign data A with an ed25519 public key and then check it against the private key. Yes, that means publishing the private key to the blockchain - it is precisely the point.

With ed25519, is it possible to sign with the pubkey and verify with the private key? Or is this not possible?


in vote coin we encrypt voting ballot using ed25519 public key

And decrypt using the private key

btw, the questioner may publish the private key to the blockchain after the voting is finished, so that everybody can verify how which accounts voted so that everything is fully auditable :slight_smile:

btw little disclaimer… the encryption using the methods for signatures is not very crypto friendly… crypto guys would say it is not recommended, but i have not seen the proof that it is not secure
at vote coin each voting session is very short and for each voting session must be generated new account, and time span of the encryption is quite short, thats why i am quite confident it is ok for our usecase… i dont know execatly what you are planning to do, so i cant say if in your use case it will be ok :slight_smile:

1 Like

Thanks for the quick response Ludo! Taking a look at it now.

Basically there are two actors, Alice and Bob. Alice has Algo and wants Monero, Bob has Monero and wants Algo. Through a protocol they are able to trustlessly do a swap, despite Monero not having any scripting capabilities. It’s done by purposefully leaking secret keys.

On Monero there are view keypairs and spend keypairs for each “address”. You and I can can generate a pair of spend keys. We exchange our public ones, pk_spend_hash and pk_spend_scholtz, but keep our private keys sk_spend_hash and sk_spend_scholtz to ourselves.

We can combine our pk spend keys into pk_spend_hash + pk_spend_scholtz ≡ pk_spend. Sending XMR into pk_spend is the equivalent of locking it up into a “multi-sig” address that requires sk_spend_hash + sk_spend_scholtz ≡ sk_spend to spend its contents.

On Algorand side, to fulfill the atomic swap protocol, we need to have the ability for smart contracts to gatekeep logic based off of providing the right private key. In this case, we want to be able to store pk_spend_hash from the start (i.e. by signing data A with it and storing the resultant signature B), and to later be able to provide the sk_spend_hash to fulfill an inverse ed25519verify opcode operation. Assume that the smart contract is holding some Algo in escrow that I can only gain by leaking my sk_spend_hash. Once I have leaked it, you can grab it, combine it with your sk_spend_scholtz, get sk_spend and thus have full spend access to pk_spend.

I explain it better in the link.

So the answer here is that if you convert your ed25519 signing key pair into curve25519 key pair it is possible to sign with the public key and then verify with the private key?

The next question I’d ask then is if this is something that could fit within the opcode budget?

I also asked this question in .

Seems like if the private key is submitted an alternative opcode could be to simply generate the public key and do a ‘==’ against what was already stored in the smart contract?

LibSodium offers this as a function, and can be seen here:

docs for crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk)