First of all, information is encrypted using public key and decrypted using private key, not the other way around (that is signing and verifying).
First time A
stores data, A
will generate new keypair (private and public key) from hash or that data itself.
After that A
will first encrypt data using newly generated public key and after that encrypt newly generated private key using her own public key. When transferring A
will decrypt newly generated private key and encrypt it using B
's public key.
Then B
can decrypt that private key using his own private key and then decrypt data using that private key and confirm that it is indeed same data (since he can decrypt it, and if A
put wrong data on blockchain than she would not be able to decrypt it).
Now you can decide if you are going to generate keypair everytime data is changed or you are going to use keypair from first data entry on blockchain. And if B
wants to restrict access to A
when B
next time changes data, B
just has to generate new keypair from altered data.
Contract will need one event with string encryptedPrivateKey and string encryptedData.
When transferring you will just put B
's address alongside private key encrypted with B
's public key in another event.
In dapp you will notice B
if his address is in transfer event and try to decrypt data and if it works transfer is legit.
Sorry, it cannot be done safely on Ethereum blockchain with standard solidity, not in that mode. If you should encrypt using solidity in a smart contract, all the variables involved in the elaboration are stored on/in the blockchain. It can be formally demonstrated.
What you can do is to store any already crypt value on the blockchain, readable by any person who knows the encryption key.
This (the decryption) requires to be made off chain (i.e. on a separate server and/or in JavaScript on the web UI) if the data must be accessed by more than one user and need to remain secret, because if you decrypt it on EVM using some
decrypt (address encryptedData, uint256 key) returns (byte32 decryptedData)
a copy of the key shall be available on the blockchain forever, readable by all (you can read the transaction in clear text on etherscan, for instance)
You can have something useful by zk-SNARK algorithms, see https://link.medium.com/Gj2AvUVMeR , but it is not trivial and, until now, no suitable implementation are known in Solidity and EVM.
Best Answer
Since all transactions and data on the blockchain are public, you need to encrypt the data outside of Ethereum and insert the already encrypted data. Similarly you need to pull the encrypted data and decrypt it locally. I'm sure there are a lot of crypto libraries for javascript that will allow you to do this, web3 I doubt contains such functionality as it's out of scope for it.