1.2.5 • Published 10 months ago

@yv-work/true-random-sol v1.2.5

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
10 months ago

Simple. Cheap. Secure.

True Random is a blockchain smart contract utility designed to provide all users with the most secure and simple yet cheap (relatively) way of generating random numbers...


Table of Contents


RNG theory

Random number generation is a process of generating a sequence of numbers or symbols that cannot be reasonably predicted better than by chance.

Currently, true randomness in code can only be achieved by hardware random number generators that use electrical, thermal or optical noise as a true, unpredictable, physical source of statistical variation. An alternative to true HRNGs generation is algo-driven generation, which is used by many systems and programming languages.

Any algorithm-driven RNG is in theory fully predictable and therefore exploitable. Algo PRNGs are usually designed to generate a random output from a given seed; the most commonly used seeds are timestamp and server file system. Any output produced by an algorithm can be considered predetermined and is therefore susceptible to forgery if sufficient computing power is available. Using the system timestamp as a seed simply means that:

Given sufficient computing power, an occurrence of the desired hash output of the algorithm with a timestamp as seed can be found in the reasonably distant future.

Problems and complications

"While a pseudorandom number generator based solely on deterministic logic can never be regarded as a "true" random number source in the purest sense of the word, in practise they are generally sufficient even for demanding security-critical applications." - "True" vs pseudo-random numbers

A DLT/blockchain architecture presents some obstacles to achieving this state.

Off chain computation alternative

While an off-chain algorithm or HRNG machine can provide a more truthful RNG, an oracle or centralised connection is required to deliver data to the chain. Such design poses two major problems for malicious attacks by the malicious off-chain logic (influencing randomness in certain way), by the oracle provider or the off-chain server owner. While decentralised oracles begin to exist, the call cost is simply too high to use such data source for a large number of on-chain computations.

Blockchain predetermination

Any attempt at randomness is further sabotaged by the fact that blockchain and DLT of any kind are completely predeterministic by design, as every node is expected to compute and confirm the same result as every other node. Any future or past event on chain can be calculated and confirmed locally.

Falsification of timestamps

Another solution would be to rely on the timestamp as the seed. This leads to numerous problems. One of them is that the source of the block timestamp is determined by the block miner. Malicious miners can shift a block's timestamp within a 10-14 seconds window of block being created. Since the block time is not constant and varies between 1 and 19 seconds depending on many factors, miners have a safe period of few seconds in which to shift the timestamp and create a "random" number.

See Note #3 under "Special Variables and Functions" section of official solidity documentation.

block.timestamp Refresh Rate

Assuming all block miners are not malicious, updating block.timestamp still takes a few seconds, so creating 5 values for 5 calls from 5 accounts within a block can result in accounts receiving identical pseudo-random results. Similarly, multiple calls for random numbers within a client transaction.

Identical RNGs returned

TL;DR

To sum up: 1. RNG cannot be placed off-chain 2. RNG cannot fully rely on user-generated input 3. RNG cannot fully rely on the timestamp provided by the call 4. RNG cannot fully rely on any other value with same or lower refresh rate than block.timestamp

There are few ways to avoid or prevent the malicious misuse of pseudorandomness by each of potentially malicious actors.

TrueRandom.sol solution

A comprehensive understanding of blockchain PRNG problems points the way to what we believe is one of the best solutions in terms of security with reasonable cost-effectiveness. In this section we explain each possible option that can be used to solve some of the problems highlighted.

Smart Contract/User generated salt

Sending msg.sender, msg.value, user call parameters or balances as a salt will lead to an easily predictable result. However, such input can completely mitigate any third-party involvement or malicious shifts by the node owner or block miner, as the algorithm does not rely on a variable within their control.

:heavy_check_mark: This salt is vulnerable to the 2nd problem, but protects the PRNG from vulnerabilities 4 and 3.

PRNG stored salt

Another option is to store salt in the random number generator. Each time the RNG is called, the salt must be updated with the result of the previous algo hashing.

PRNG stores salt 1, user A generates a random number 74 from the hash with salt 1, the number 74 is stored as salt for the next call. User B requests the next number and generates number 13 from salt 74. Salt 13 is stored for the next call of the PRNG.

The use of stored Salt eliminates user's ability to influence the seemingly predictable hashing algorithm, but poses a great risk for an attack on the 3rd vulnerability, as any private property of the smart contract can theoretically be read from the binary state of the smart contract storing such value. This results in some "frontrunning" risk if the node owner can exploit such knowledge to hijack the best possible hashing output for himself by precompiling outcome off-chain to then abuse it when the on-chain app uses this value for its computations (and if RNG is the key to some advantageous app/game outcomes ). Assuming several apps call a single smart contract at irregular intervals, a common RNG source is frequently updated with new values which lowers any option of predictability.

:heavy_check_mark: It is reasonable to assume that this option completely protects PRNG from the 2nd and 4th problems, but makes PRNG vulnerable to the 3rd potential attack.

block.timestamp

Despite the poor refresh rate and potential malicious shitfing, the block.timestamp value is limited to a certain range or options set by the system (+ malicious miners). Therefore, this value is completely independent of the user and cannot be abused.

:heavy_check_mark: Block.timestamp can therefore be considered a reasonably reliable protection against the 2nd problem, although it is vulnerable to the 3rd.

Combined solution

So instead of using one specific PRNG source, TrueRandom.sol combines all 3 options in order to generate byte record that's virtually protected from all attack anglesd by all combined seeds.

TrueRandom.sol Salt assembly

To stay within 32B to 32B conversion (proven to be cheaper than direct encoding and reliable in regard to integer overflow, PRNG trims all incoming variables to fit such bytes structure. As of solidity 0.8.8 variables are always trimmed down so the produced timestamp value is always made form lower, refreshing digits.

Unpredictability of such PRNG lies in the idea that system, other developers, potentially miners, as well as user, all have influence on hashing algorithm. So despite unequal influence of said parties, no single entity can reasonably predict hashing output better than by chance. Fulfilling the key demand of "True" RNG.

Usage & Examples

To help with TrueRandom implementation we provided you some examples of direct Smart Contract on-chain usage as well as SDK integration.

On-Chain integration guide is also provided in ./contracts folder - Simply assign Interface to a new variable and set it to the Const address:

import "@yv-work/true-random-sol/contracts/ITrueRandom.sol";
import "@yv-work/true-random-sol/contracts/TrueRandomConst.sol";

contract Example is TrueRandomConst {

    ITrueRandom rand;
    
    constructor() {
        rand = ITrueRandom(TrueRandomConst.HEDERA_TESTNET);
    }
}

Currently deployed only on Hedera previewnet, testnet, TrueRandom.sol contains set of useful functions to protect your randomly generated numbers, make more cost efficient calls with less security but for 80% gas needed and utilise general mechanism which makes this smart contract sufficiently unpredictable.

Logos for your project can be found in /docs/.

P.S. Donations are welcomed :-)

  • Hedera - 0.0.1026509
  • Ethereum - 0xe8D6A5a34627cEd482c2E6488b2C367d09295f86
1.2.5

10 months ago

1.2.4

10 months ago

1.2.3

1 year ago

1.2.2

1 year ago

1.2.1

2 years ago

1.2.0

2 years ago

1.1.4

2 years ago

1.1.3

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago