Lets bring the ‘70s to Ethereum
PGP and SSL certificates. These are the names which pop in most heads who have heard the term PKI or public key infrastructure before.
For the last two decades, PKI was kind of equal to RSA. It is a brilliant, easy to understand method for public-key cryptography. Today you can also use elliptic curve cryptography for the same, which offers space savings. For the same level of security it requires smaller key sizes. On the flip side it takes a bit more effort to understand it.
This doesn’t mean RSA would be superseded. It is used more widely than ever. Do you have a government issued ID card? More likely than not, it uses RSA. Do you have credentials for online banking or taxation? The same. Do you have an encryption token from your employer? Ditto. Do you encrypt/sign important emails? Mostly that is done via PGP, which uses RSA.
Since it is used so widely, perhaps it would make sense using it in Ethereum. In particular, verifying that an RSA signature was generated by a given public key would be useful. In short, verifying if it was signed by the sender.
Some of the use cases this would enable:
- Using an RSA key to sign transaction with a contract. This includes your encryption device as well government ID cards.
- Verifying certificate structures in smart contracts.
- Using government ID cards to prove individuality.
Use cases which are not meant to be supported in Ethereum are:
- Encrypting using RSA keys in contracts. All contract data is public, there is no point to encrypt something for a recipient.
- Decrypting using RSA keys in contracts. The keys held by a contract are public too.
- Creating RSA signatures. The same, keys would be public.
This sounds great. Can I do it already?
Yes, … and no.
You can implement RSA in EVM (and its languages, Serpent and Solidity). For laughably small (~ a few bits) key sizes you could do that without a big number library. Implementing a big number library used in this order of performance would be cost prohibitive. Simply it would cost more gas, than its usefulness is worth.
There are three more rational solutions:
- Implement an oracle (aka. external data provider) to do RSA calculations. You must trust this service and that is not a good position to be in with cryptography.
- Wait until this improvement proposal is accepted.
- Wait for EVM2.0, the next generation of the Ethereum machine, which would provide near-native performance for contracts. RSA could be written in a contract efficiently.
I’m inpatient. Period.
Don’t be. With all the nice tools available for Ethereum, I’ve created a sample implementation in Javascript.
It has two components:
- The proposed precompiled contract called rsaverify implemented in ethereumjs-vm.
- A small wrapper written in Solidity assembly to provide the rsaverify method to contracts.
All this is bundled up in the browser-solidity app for easy testing.
Will you finally show me some code?
//
// RSA signature verification
// <msg> is the original message hash
// <N> is the N component of the public key
// <e> is the e component of the public key
// <S> is the signature
// <paddingScheme> is the scheme used, 1 stands for PSS
//
function rsaverify(bytes msg, bytes N, uint e, bytes S, uint paddingScheme) returns (bool);
And now, read this Github repository for technical explanation and links to sources.
What to do next? Can I help?
Absolutely! This is pretty much work in progress. You can help with the following:
- Defining the API suiting all use cases, with consideration to how the contract ABI and languages work.
- Defining gas costs for different RSA key sizes.
- Providing sample implementations for geth (Go) and eth (C++). (But don’t ask the maintainers to merge it!)
Ethereum change requests (EIPs) have a better chance of acceptance if there are people actually needing that feature and all the small implementation details are worked out.
With your help, this might become a supported feature in subsequent Ethereum (hard) forks.
(*) I’m confused by the title. Does it mean anything? It does. RSA was invented in 1973 and 1977.