I'm working on smart contract which once in a while pays one of the users a prize, prize winning is based on random number generated in each tx.
Question is: is it save using pseudo random number in example generated of block.hash or block.timestamp if the prize is never very high (up to 0.5 ETH)? Would that be even worth of manipulating by the miners?
Are there any walk-arounds that could help avoid such a high fees like using oracles?
Fees of using Chainlink VRF random number come to 0,017 ETH, which is quite high if considered using it in each trade.
Related
In my cryptography lessons I learned that one should use as many parameters together as possible in order to have the entropy to generate a close to perfect random number. My question is: Let's say I would just measure the temperature of room at a given moment (e.g. 19,6573°C), would the number not be already random enough? I mean an attacker could not possibly guess my room temperature and he could also not measure it afterwards, because he would need to go back in time.
Since cryptographic algorithms would turn my temperature from 19,6573 to a string of 512 characters or more and an attacker would not be able to reproduce the measurement, my random number should be random enough, shouldn't it?
I've done quite a bit of checking up on other questions and I'm still uncertain on the issue.
Here's my usage case:
I have an online shopping cart. Occassionaly, certain clients find the ordering process either too tedious, or there are some clients where an online order will not cut it, and they need an actual PDF estimate (quote) in order to purchase a product.
So I coded in a module that takes the shopping cart contents, and lays out neatly as a PDF estimate.
Now because this process only uses the cart contents, and nothing else is used, not even the database, I have to create a unique Estimate document number, so that should the client pay for the quote, they have a reference to use in their payment instruction.
The shopping cart currently generates a 5 digit cart ID, unique to each customer based on their session. I've taken this 5 digit cart ID, and I've then added UNIX time to it, which gives me a nice long number to use as the Estimate document number.
So I end up with something like this: 363821482812537 [36382 is the cart ID and 1482812537 is unix time at the time the PDF estimate was generated]
The problem with this is that it is too long, and WILL be an issue as bank payment references are limited. Ideally, I'd like to keep it to 10 characters or less.
I've decided to look at CRC32 to shorten the generated estimate numbers, and it seems capable of shortening the estimate number to an acceptable amount of characters.
But, can anyone shed some light on what kind of collision I might be up against?
Few things to consider:
Cart ID will always be 5 digits.
Unix time will always be 10 digits up until the year 2286.
[So we will always end up with 15 digits that needs to be encoded, and no more]
There is a safeguard in place, that if by some chance, a duplicate occurs, an error is thrown, and the the option is provided to retry and generate the estimate. This is done by the estimate saving to a filename matching the estimate number (or in this case, the CRC32 hash of the estimate number) - and then checking first to see if a filename with the hash exists.
Customers will for the moment not be allowed to generate estimates themselves, for reasons not important to my question. So it will only be admins who can generate estimates.
My concern is simple, will I find myself running into collisions very often with my 15 digit to CRC32 hash encoding, or is it going to be pretty rare to run into collisions?
Why not just maintain an estimate number that you simply increment each time you need a new one? You are already effectively maintaining a list of used numbers to check against for collisions, so just put your counter there. Then you only need to look at one thing instead of n things. By taking the CRC, you are discarding information you might try to extract from the estimate number, so there was no point in making the ID out of that information in the first place. Your approach seems way more complicated than it needs to be.
The probability of an individual collision is 2-32. The data content doesn't matter, so long as it's more than 32 bits, which it is in this case, since a CRC does a very good job mixing the bits. However you have n chances at a collision if you have previously generated n estimates. So as n grows, the chance of a collision grows accordingly. (See the Birthday Problem.) As a result, after only 77,164 estimates there is a probability of 50% that two of their hashes collided.
I want to set up "public lottery", in which everyone can see the selection is random and fair. If I only needed one bit, I would use, for example, the LSB of the closing Dow Jones index for that day. The problem is, I need 32 bits. I need a source that is:
available daily
visible to the public throughout the world
not manipulable (by me or anyone else)
unbiased
simple
I suppose I could just pick 32 stocks or stock-indices and use the LSB of each, that would be at least difficult to manipulate, and run them through some hash to eliminate any bias toward 0, but that doesn't really qualify as "simple". Other thoughts: some feed of meteorological or seismological data. That would be more difficult to manipulate (much easier to buy a share of stock than to cause an earthquake) but harder to authenticate (since there aren't armies of auditors watching weather data).
Any suggestions?
Check out http://www.random.org/ They have a section for Third-Party Draw Service
The Third-Party Draw Service is useful for people who operate raffles,
sweepstakes, promotional giveaways and other lottery type services
professionally. In a similar fashion to a certified official,
RANDOM.ORG acts as an unbiased third party who conducts the drawings
in a manner that is guaranteed to be fair and truly random. The
drawings are made using true randomness that comes from atmospheric
noise, which for many purposes is better than the pseudo-random number
algorithms typically used in computer programs.
Check out the Public Records for details about recent drawings held
with the service.
This sounds like what you are looking for, but you would end up having to rely on random.org for the numbers.
The part "visible to the public throughout the world" is the trickiest part in my opinion.
An excellent source of really random numbers is the noise on a webcam (or any other CCD camera). This noise is caused by quantum fluctuation of electron temperature on the CCD plate, so it's truly random.
You could use a picture from a publicly available webcam, but it's hard to find one with a closed shutter... You could set one up and make it available yourself, or you could use one that monitors some meteorological event and subtract a time-averaged image every day.
I hope this is simple enough!
Look at the XKCD GeoHashing algorithm.
MD5(Date, Dow Jones Opening)
Depends how "simple" you want.
I would take a large set of unrelated inputs. You could include some or all of these:
Stock prices (preferably from multiple locations, e.g. Last digit of Dow Jones + last digit of FTSE)
Last digit of the reading from a publicly-visible digital thermometer (easy to find in large cities)
The date
MD5 sum of the current google.com logo image
Name of top-billed guest on today's episode of <insert name of TV talk show here>
Other public lotteries
Concatenate all of these into one large string and apply a cryptographic hash function to it.
The hash will not increase the total entropy, but what it will do is make the output harder to manipulate (because the attacker would need to manipulate many inputs simultaneously.)
Now just take the first 32 bits of the hash.
Separate the non deterministic from the random use a third party service that streams random number sets with a sn assigned to each set.
you set up the number of bits and the number of digits in sn.
Now it streams in random sets with assigned sn in a loop the size of your sn. Save it and you get a batch set of numbers that you put out for public record
Now you can chose a smaller number that doesn't need to be random, just non deterministic to pick the single set of numbers
I've heard people being warned all over the place not to rely on a language's random() function to generate a random number or string sequence "for security reasons." Java even has a SecureRandom class. Why is this?
When people talk about predicting the output of a random number generator, they don't even need to get the actual "next number". Even something subtle like noticing that the random numbers aren't evenly distributed, or that they never produce the same number twice in a row, or that "bit 5 is always set", can go a long way towards turning an attack based on guessing a "random" number from taking years, to taking days.
There is a tradeoff, generally, too. Without specific hardware to do it, generating large quantities of random numbers quickly can be really hard, since there isn't enough "randomness" available to the computer so it has to fake it.
If you're not using the randomness for security (cryptography, passwords, etc), but instead for things like simulations or numerical work, then it doesn't matter too much if they're predictable, only that they're statistically random.
Almost every random number generator is 'pseudo random' in that it uses a table of random numbers or a predictable formula. A seed is sometimes used to "start" the random sequence at a specific point, e.g. seedRandom(timer).
This was especially prevalent in the days of BAsIC programming, because it's random number generator always started at exactly the same sequence of numbers, making it unusable for any kind of GUID generation.
Back in the day, the Z-80 microprocessor had a truly random number generator, although it was only a number between 0 and 127. It used a processor cycle function and was unpredictable.
Pseudo-random numbers that can be determined in advance can lead to security holes that are vulnerable to a random number generator attack.
Predictability of a random number is a big issue. Most "random" functions derive their value from time. Given the right set of conditions you could end up with two "random" numbers of a large value that are the same.
In windows .NET world CPRNG (Cryptographically secure pseudo random number generator) can be found in System.Security.Cryptography.RandomNumberGenerator through underlying win32 APIs
In Linux there is a random "device"
As the title says: What is the difference between a non-secure random number generator and a secure random number generator?
No computationally feasible algorithm should:
recover the seed, or
predict the "next bit"
for a secure random number generator.
Example: a linear feedback shift register produces lots of random numbers out there, but given enough output, the seed can be discovered and all subsequent numbers predicted.
A secure random number should not be predictable even given the list of previously generated random numbers. You'd typically use it for a key to an encryption routine, so you wouldn't want it guessable or predictable. Of course, guessable depends on the context, but you should assume the attacker knows all the things you know and might use to produce your random number.
There are various web sites that generate secure random numbers, one trusted one is hotbits. If you are only doing the random number generation as a one off activity, why not use a lottery draw result, since it's provably random. Of course, don't tell anyone which lottery and which draw, and put those numbers through a suitable mangle to get the range you want.
With just a "random number" one usually means a pseudo random number. Because it's a pseudo random number it can be (easily) predicted by an attacker.
A secure random number is a random number from a truly random data source, ie. involving an entropy pool of some sorts.
Agree with Purfiedeas. There is also nice article about that, called Cheat Online Poker
A random number would probably mean a pseudo random number returned by an algorithm using a 'seed'.
A secure random number would be a true random number returned from a device such as a caesium based random number generator (which uses the decay rate of the caesium to return numbers). This is naturally occurring and can't be predicted.
It probably depends on the context, but when you are comparing them like this, I'd say "random number" is a pseduo random number and a "secure random number" is truly random. The former gives you a number based on a seed and an algorithm, the other on some inherintly random function.
It's like the difference between AES and ROT13.
To be less flippant, there is generally a tradeoff when generating random numbers between how hard it is and how predictable the next one in the sequence is once you've seen a few. A random number returned by your language's built-in rand() will usually be of the cheap, predictable variety.