I’m working on a project where all data is stored encrypted on a blockchain. There are some off-chain compute nodes that have the key to decrypt the data and perform some computation and return results. I’d like to design a scheme where one can verify that computation is correct using smart contract. So, I’m thinking to have a smart contract that implements the verification function. Verification function would have two arguments: a key for decryption and the expected result. The function is constant, so private key should not be written to blockchain, hence remain hidden from all. The function returns true or false and signs this result. This function can be called only by the entity that knows the key. In order to implement the above, I need a function for decryption and for signing in Solidity, but I was not able to find any.

Any advice if decryption, signing function exist in Solidity? Any libraries? Any advice on alternative designs for my problem

  • 1
    If the private key never reaches the blockchain and is only used in a constant function, there's no particular benefit to the code for that function being on the blockchain. Write it in a normal language and save yourself the pain of trying to do it in Solidity. Feb 13 '18 at 6:14
  • To clarify why what you describe doesn't work, contracts don't have private keys and thus can't sign anything. (Even if they did have private keys, those keys wouldn't actually be private. Anyone running an Ethereum node would have access to the private key and could then sign anything.)
    – user19510
    Feb 13 '18 at 6:52
  • his req seems to be he will save some encrypted data in blockchain and he will write verify(key, encryptedData) that returns bool. @MarkS Correct me if I am wrong. Feb 13 '18 at 7:52
  • @EdmundEdgar, the value that I see in doing the verification in contract is that anyone can see the verification code. So the answer "true" / "false" is more trusted. if I pass the private key as an argument to a function that does not update the blockchain state (constant function), then the key would remain private - correct?
    – Mark S.
    Feb 13 '18 at 14:16
  • If you really have to share the verification code via the contract you can save it on IPFS, and publish its IPFS hash to the contract. Feb 13 '18 at 14:20

As per your qus, yes you can do. But unfortunately I couldn't find any encryption libraries in Solidity. In general good encryption/decryption algorithms requires good computational power. That means it requires more gas. I feel this is cost effective.

Let me summarise with code:

contract Mail{
    mapping(address=>string) loginInfo;
    function validate(bytes key, bytes expectedResult) public constant returns(bool){
         //Check given saved data  
          //To do check given data and decrypted data is same or not?
       return true;


Instead of doing this, you can follow another way:

  1. Upload data to IPFS
  2. Save IPFS/Swarm address and hash of encrypted data in your contract.
  3. When you want to verify then get the Swarm/IPFS address and hash value from contract.
  4. Use ifps/swarm api/sdks to getting the data.
  5. Hash of step 4 with contract hash value if both are same then follow step6
  6. Use any client library to decrypt data
  7. Compare your data with decrypted data.

In above method, your original data will not go to network.

Eg: contract,

contract Mail{
    struct MailInfo{
        bytes ipfs;
        bytes enc_hash;
    mapping(address=>MailInfo) loginInfo;
    function getIPFS(address userId) public constant returns(bytes,bytes){
       return (loginInfo[userId].ipfs,loginInfo[userId].enc_hash);


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.