Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
As part of the Chainlink Virtual Hackathon, developers Kyle Santiago, Thomas Potter, William Santiago, and Thomas Greco used Chainlink VRF to create secure one-time pad encryption keys. Using blockchain RNG to secure message encryption is an exciting use case as encryption relies on random number generation as a core mathematical and security assumption. In this post, Kyle Santiago explain how their team generated verifiably random encryption keys on-chain using Chainlink VRF.
Before the advent of asymmetric cryptography, which enables blockchain technology, there was no real way to trustlessly send messages over insecure channels. The way most encryption algorithms worked before this innovation was by using symmetric cryptography. One significant encryption method using symmetric cryptography is the One-Time Pad (OTP).
One-Time Pads are unbreakable ciphers where a random key, which is at least the same length of the message, is used to encrypt a message. As the name suggests, the key is used only once to ensure that it remains uncrackable.
How to Encrypt Plaintext Messages
Encrypting a plaintext message is straightforward. First, we convert the letters of the original message into numbers. Then we generate a random key to add to the original message, creating a new and encrypted version of the original plaintext message. Only the people who know the key can decrypt the message.
For example, to encrypt the message âhello thereâ, the message needs to be converted to its number equivalent of the 26 letter alphabet and split up into pairs. In this case, that message would become â08 05 12 12 15 20 08 05 18 05â. Then we generate a random number key of at least the same length as the message to add to the original message. Letâs say we generate a key that is â07 15 12 09 01 06 11 08 03 02â. Adding them together using simple arithmetic, we get:
08 05 12 12 15 20 08 05 18 0507 15 12 09 01 06 11 08 03 02 +15 20 24 21 16 26 19 13 21 07
â15 20 24 21 16 26 19 13 21 07â is âO T X U P Z S M U Gâ when converted back to alphabet characters. Before sending this encrypted message to another party, you need to share the key with them so they can decrypt the message. Then we send the encrypted message to the other party who uses the shared key to decrypt it.
This process is similar to encrypting the original message; the only difference being that subtraction is used instead of addition. Subtracting the encrypted message by the key using simple arithmetic, we get:
15 20 24 21 16 26 19 13 21 0707 15 12 09 01 06 11 08 03 02 -08 05 12 12 15 20 08 05 18 05
Converting â08 05 12 12 15 00 08 05 18 05â gives us the original message as âhellothereâ. As long as we never use the key again to encrypt the message, this encrypted message is virtually uncrackable.
The Importance of Generating Good Keys
Simple plaintext encryption in this manner can be effective for simple needs. Still, some security dependencies leave our encryption open for attack. Insecure random number generation is one of these attack vectors. Remember the part where we generated a random key? What happens if that key is generated in an insecure manner? What if our randomization method isnât really random? And what if the attackers know the pattern of the so-called randomization method?
This is known as pseudorandom number generation, and it turns out that many, supposedly, random numbers are really not. Using a pseudorandom number generator makes the encrypted message much easier to crack for anyone who infiltrated the message. This is a case where Chainlink VRF can enhance encryption security.
Chainlink VRF allows us to generate randomness while proving that it was created in a tamper-proof way. The way it works is that a user sends a seed number from a smart contract to Chainlink oracles, which use it to generate a random number. That number is then sent back on-chain to the smart contract along with the proof that it was generated with the user-provided seed. The proof allows for the userâs smart contract to verify randomness to ensure that the number was not generated in a predictable and/or malicious manner.
We designed our project, the Chainlink-OTP project, to mitigate the pseudorandom number generator problem that most One-Time Pad generators have. We used Chainlink VRF to request random numbers from Chainlink oracles and used those random numbers to generate the pads. Users can verify that we created pads using provably fair randomness to encrypt their secure messages.
Chainlink-OTP currently calls the Chainlink VRF to a smart contract to create a verifiably random encryption key, which will eventually help us build a messaging system to encrypt and decrypt plaintext messages.
The Code
Now that weâve established a high-level overview of the project, letâs get into the code itself. Here is a link to the GitHub repository where the front end web app is stored. Letâs walk through each step to generate the one-time pads using the random number generated from Chainlink VRF.First, the smart contract containing the VRF code needs to be deployed on-chain; we used the Kovan testnet chain. Use this documentation for reference on deploying the contract: https://docs.chain.link/docs/get-a-random-number. Once the contract is deployed on-chain, we can use that in the code.
```const VRFaddress = "0x2487d4ec9c4a721595925005be6fd2eba0c5628b"; const vrfContract = new eth.Contract(abi, VRFaddress); var seed = parseInt(Math.random()); const tx = { // this would be the userâs address from: null, // target address, this is the deployed VRF smart contract address to: VRFaddress, // data for the specific VRF number function we want to use data: vrfContract.methods.getRandomNumber(seed).encodeABI() }; const vrfNumber = async () => { var allowed = true; await window.web3.eth.getAccounts().then(async e => { if(!e[0]){ window.ethereum && window.ethereum.enable(); allowed = false; return; } tx.from = e[0]; var result = await window.web3.eth.sendTransaction(tx); return result; }) if(!allowed) return []; var result = await vrfContract.methods.randomResult().call(); return result; }```
This code is from the smartContract.js file where the `vrfNumber` function sends a transaction from the userâs address to the deployed VRF contract to request a new VRF number. Once the new VRF number is posted back on-chain, weâll use it to generate the one-time pads.
For the actual pad generation, the front end web app calls a function `genPads(length)` which takes a length (default 7) and returns character arrays which are used as pads. The function generates the pads by taking the VRF number returned by calling `vrfNumber` and changing each number with its corresponding ASCII character and storing it into an array. It then calls `chunkArray()` which turns the large array into small chunks, the length of which is defined by the length parameter. Finally, it deletes any remaining arrays whose length is smaller than the length parameter. The full code can be found in the VRF.js file.
```async function genPads(length){ var vrfNum = await vrfNumber(); const arrayOfDigits = Array.from(String(vrfNum), Number); var arrayOfLetters = []; for(let i = 0; i < arrayOfDigits.length; i++) arrayOfLetters.push(String.fromCharCode(97 + arrayOfDigits[i])) arrayOfLetters = chunkArray(arrayOfLetters, length); for(let i = 0; i < arrayOfLetters.length; i++){ if(arrayOfLetters[i].length < length) delete arrayOfLetters[i]; } return arrayOfLetters; }```
We now have one-time pads that allow us to encrypt a message, and if we share the pad with a contact, they can decrypt the message.
Next Steps for Chainlink-OTP
In future development, we will allow users to not only generate pads but also to type a message that could be encrypted using those pads. This would automate the way users encrypt and decrypt their messages and make the whole process a seamless messaging app.
Initially, we anticipate counting up the number of characters in the entire message to make a rough estimate of the needed VRF number length to call the oracles enough times to cover each character of the original message. This way, users who wanted to encrypt larger messages would need to pay more gas fees than those who wanted a small message encrypted due to the amount of Chainlink VRF calls required. There are also opportunities to use a gas price estimator and several other features that access on-chain data.
Overall, we had a great time implementing Chainlink VRF and were pleased with how easy it was to integrate into our web app. We plan on building more applications using Chainlink VRF and expanding the use cases with universally connected smart contracts powered by Chainlink.
Start Building with Chainlink VRF
If you are a smart contract developer and want to take advantage of Chainlink VRF for generating verifiable randomness for one-time pads and other applications, visit the Chainlink developer documentation.To stay up-to-date with all things Chainlink, visit chain.link, follow @chainlink on Twitter, and join the technical discussion on Discord.Website | Twitter | Discord | Reddit | YouTube | Telegram | Events | GitHub | Price Feeds | DeFi
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.