# Verifiable Randomness on StarkNet with Drand ### Why Verifiable Randomness Verifiable randomness is a way to secure the result of an off-chain pseudorandom function on-chain. This allows us to have effectivley a random number generator on StarkNet without having to generate the number itself using smart contracts. With a random number generator we can pursue the creation of different games of chance on StarkNet. ## Drand network Rather than setting up our own infrastructure to generate a random number along with the pieces required for proving, we can leverage the [Drand Network](https://drand.love/) In a set interval the Drand network emits a payload that is publicly available via an http call ``` { "round": 1597683, "randomness": "24138936fcbf7fc3951c928158be6998cee3af622142d0790333608d17a5c5f6", "signature": "8c04905c0adf34f1fb007915d9ccc7d07b97305fc63952726f9367c87f36ab687c5e190c151f6ac4d760a9e009fc54230adb8513885449d649a229bc727be9ff347bdbce1c609cebf993b6ae57133fbcf23f96b15dbd3510cb5f2ade6b30b647", "previous_signature": "ada42197a2db89866da4c44348f77f7868e41e961ec32e636b912d43c625386afae9e54944ac573047dbd227ee495b52059586c8d8cd0edfe18cc15ca0666a66651da1d62b12af2d0fac19735bed9298690a593571965c3ad7c7b11947e76ec0" } ``` additionally a public key of the Drand network is avalable ``` "public key" : "51e1014efb8be0c0c8c70cec1473a0d5b2f40d3d926635b9e74c41f89673f6b37c0c752f67419a32db91abf31360d8659471b8709040cf650e908db7f4bda9308e01400477e3f586ccb607d7bcd47a0272cca6ec52d38d2599aedc70788f739a8dc265b7aaf7b6fd4aeb67058cbe5c586024c97068321117958b871741758b89" ``` ## Verifying on StarkNet Without going into detail about how Drand generates a random number ([Read more here](https://drand.love/docs/cryptography/#beacon-phasee)) the Drand payload and public key above is generated using pairing based cryptography. With a random number `R`, a signature `S`, and a public key `P` we can call a verification function in a smart contract that does the typical verification steps in pairing based cryptography. (Pseudocode below) ``` verify(R : RandomNumber , S : signature, P : PublicKey) g1 = generator for G1 // hash_to_G1 puts our message on the prime sub-group G1 // of eliptical curve (BLS12-381) hashed_msg = hash_to_G1(R) // Putting our signature back on the eliptical curve group E1 e1_sig = string_to_E1(S) p_1 = pairing(P, hashed_msg) p_2 = pairing(g1, e1_sig) assert p_1 == p_2 return ``` These auxilary functions `hash_to_G1`, `string_to_E1` and `pairing` are typical processes in pairing based cryptography. Specificaly `G1` is a bilinear groups of a generator `g1`. The generators used in the instance of Drand is [BLS12-381](https://electriccoin.co/blog/new-snark-curve/). If we are able to write this cryptography suite in cairo (with the help of hints), a smart contract holding the public key will only accept payloads that are able to prove their authenticity with a valid signature. ## Throughput of the Drand Network The Drand network posts a new randomness string every 15 to 30 seconds. This number is planned to be reduced to 3-5 seconds based on conversations with folks involved in the Drand project. This throughput is lower than many would like if the goal is to have a one to one mapping between on-chain rng requests and Drand random numbers similar to [Chainlink vrf](https://docs.chain.link/docs/chainlink-vrf/). One way to make this low throughput negligable is to hash the rng string with some unique properties of a given rng request when resolving it. This is what is being done in the [draft vrf oracle](https://github.com/0xNonCents/VRF-StarkNet/blob/main/contracts/rng_oracle.cairo#L70-L88). However the for looping of the `resolve_rng_request` function does have tradeoffs. If one callback function of an rng request fails or takes very long it will have negative consequences for the other requests. This will effect how permissionless this approach can be. A potential permissionless approach is being done by the [Dia Randomness Oracle](https://docs.diadata.org/documentation/oracle-documentation/randomness-oracle) (Ethereum Mainnet). However this implementation does not guaruntee that the rng request will be resolved by the next rng payload. And since rng comes infrequently this hurts the UX of quite a few applications too much. ## Sending Drand payloads to StarkNet Using [Drand JS](https://drand.love/developer/clients/#js) and the [Starknet Hardhat](https://github.com/Shard-Labs/starknet-hardhat-plugin) plugin [we can create a bot that sends randomness payloads to the oracle](https://github.com/0xNonCents/Drand-to-StarkNet/blob/testnet-dice/scripts/send-randomness.mjs). Since all payloads are verified on chain anyone could run a bot. As long as one bot is posting rng as soon as it is available the throughput of the oracle should roughly match the Drand Network itself. --- This concludes the outline for Verifiable Randomness on StarkNet. Feel free to check out the draft [contract](https://github.com/0xNonCents/VRF-StarkNet) and [bot](https://github.com/0xNonCents/Drand-to-StarkNet) repositories. Or learn more about Drands particular flavor of BLS with the following resources: [BLS12-381 for the Rest of Us](https://hackmd.io/@benjaminion/bls12-381) [BLS12-381 Go](https://github.com/drand/bls12-381) [BLS signature specification used by drand](https://datatracker.ietf.org/doc/html/draft-boneh-bls-signature) [BLS Signatures in Solidity](https://hackmd.io/@liangcc/bls-solidity)