security - PHP Seeded, Deterministic, Cryptographically Secure PRNG (PseudoRandom Number Generator). Is it possible? -
i'm required create provably-fair (deterministic & seeded) cryptographically secure (cs) random number generator in php. running php 5 , php 7 isn't option right now. however, found polyfill php 7's new cs functions i've implemented solution (https://github.com/paragonie/random_compat).
i thought srand() used seed random_int(), i'm not if case. can csprng seeded? if can seeded, output deterministic (same random result, given same seed)?
here code:
require_once($_server['document_root']."/lib/assets/random_compat/lib/random.php"); $seed_a = 8138707157292429635; $seed_b = 'juxj1xlnbkk7gpasr80hjfq5ey8qweic8bt'; class csprng{ private static $rngseed = 0; public function generate_seed_a(){ return random_int(0, php_int_max); } public function generate_seed_b($length = 35){ $characters = '0123456789abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz'; $randomstring = ''; for($i = 0; $i < $length; $i++){ $randomstring .= $characters[random_int(0, strlen($characters) - 1)]; } return $randomstring; } public function seed($s = 0) { if($s == 0){ $this->rngseed = $this->generate_seed_a(); }else{ $this->rngseed = $s; } srand($this->rngseed); } public function generate_random_integer($min=0, $max=php_int_max, $pad_zeros = true){ if($this->rngseed == 0){ $this->seed(); } $rnd_num = random_int($min, $max); if($pad_zeros == true){ $num_digits = strlen((string)$max); $format_str = "%0".$num_digits."d"; return sprintf($format_str, $rnd_num); }else{ return $rnd_num; } } public function drawing_numbers($seed_a, $num_of_balls = 6){ $this->seed($seed_a); $draw_numbers = array(); for($i = 0; $i < $num_of_balls; $i++) { $number = ($this->generate_random_integer(1, 49)); if(in_array($number, $draw_numbers)){ $i = $i-1; }else{ array_push($draw_numbers, $number); } } sort($draw_numbers); return $draw_numbers; } } $csprng= new csprng(); echo '<p>seed a: '.$seed_a.'</p>'; echo '<p>seed b: '.$seed_b.'</p>'; $hash = hash('sha1', $seed_a.$seed_b); echo '<p>hash: '.$hash.'</p>'; $drawnumbers = $csprng->drawing_numbers($seed_a); $draw_str = implode("-", $drawnumbers); echo "<br>drawing: $draw_str<br>"; when code run, drawing ($draw_str) should same on each run, not.
to prove drawing fair, seed (seed a) chosen before winning number picked , shown. random number generated (seed b). seed b used salt , combined seed , result hashed. hash shown user prior drawing. provided source code when winning number picked, both seeds revealed. can verify hash matches , done fairly.
duskwuff asks:
how intend prove seed chosen fairly? suspicious user can claim picked seed result in favorable outcome specific users, or revealed seed specific users ahead of time.
before investigate solutions, problem trying solve? threat model?
it sounds like want seedspring (version 0.3.0 supports php 5.6).
$prng = new \paragonie\seedspring\seedspring('juxj1xlnbkk7gpas'); $byte = $prng->getbytes(16); \var_dump(bin2hex($byte)); this should return:
string(32) "76482c186f7c5d1cb3f895e044e3c649" the numbers should unbiased, since it's based off pre-shared seed, not, strict definition, cryptographically secure.
keep in mind seedspring created toy implementation/proof of concept rather official paragon initiative enterprises open source security solution, feel free fork , tweak suit purposes. (i doubt our branch ever reach "stable 1.0.0 release").
(also, if you're going accept/award bounty of these answers, aaron toponce's answer more correct. encrypting nonce ecb mode more performant encrypting long stream of nul bytes aes-ctr, approximately same security benefit. this 1 of extremely rare occasions ecb mode okay.)
Comments
Post a Comment