@@ -1285,13 +1285,29 @@ PHP_FUNCTION(random_int)
1285
1285
PHP_METHOD (Random_Engine_CombinedLCG , __construct )
1286
1286
{
1287
1287
php_random_engine * engine = Z_RANDOM_ENGINE_P (ZEND_THIS );
1288
+ php_random_engine_state_combinedlcg * state = engine -> state ;
1288
1289
zend_long seed ;
1290
+ bool seed_is_null = true;
1289
1291
1290
- ZEND_PARSE_PARAMETERS_START (1 , 1 )
1291
- Z_PARAM_LONG (seed )
1292
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
1293
+ Z_PARAM_OPTIONAL ;
1294
+ Z_PARAM_LONG_OR_NULL (seed , seed_is_null );
1292
1295
ZEND_PARSE_PARAMETERS_END ();
1293
1296
1294
- engine -> algo -> seed (engine -> state , seed );
1297
+ if (seed_is_null ) {
1298
+ int i ;
1299
+
1300
+ for (i = 0 ; i < 2 ; i ++ ) {
1301
+ if (php_random_bytes_silent (& state -> s [i ], sizeof (int32_t )) == FAILURE ) {
1302
+ zend_throw_exception (spl_ce_RuntimeException , "Random number generate failed" , 0 );
1303
+ RETURN_THROWS ();
1304
+ }
1305
+ }
1306
+
1307
+ state -> seeded = true;
1308
+ } else {
1309
+ engine -> algo -> seed (engine -> state , seed );
1310
+ }
1295
1311
}
1296
1312
/* }}} */
1297
1313
@@ -1412,11 +1428,12 @@ PHP_METHOD(Random_Engine_MersenneTwister, __construct)
1412
1428
php_random_engine * engine = Z_RANDOM_ENGINE_P (ZEND_THIS );
1413
1429
php_random_engine_state_mersennetwister * state = engine -> state ;
1414
1430
zend_long seed , mode = MT_RAND_MT19937 ;
1431
+ bool seed_is_null = true;
1415
1432
1416
- ZEND_PARSE_PARAMETERS_START (1 , 2 )
1417
- Z_PARAM_LONG (seed );
1433
+ ZEND_PARSE_PARAMETERS_START (0 , 2 )
1418
1434
Z_PARAM_OPTIONAL ;
1419
- Z_PARAM_LONG (mode )
1435
+ Z_PARAM_LONG_OR_NULL (seed , seed_is_null );
1436
+ Z_PARAM_LONG (mode );
1420
1437
ZEND_PARSE_PARAMETERS_END ();
1421
1438
1422
1439
switch (mode ) {
@@ -1427,6 +1444,14 @@ PHP_METHOD(Random_Engine_MersenneTwister, __construct)
1427
1444
state -> mode = MT_RAND_MT19937 ;
1428
1445
}
1429
1446
1447
+ if (seed_is_null ) {
1448
+ /* MT19937 has a very large state, uses CSPRNG for seeding only */
1449
+ if (php_random_bytes_silent (& seed , sizeof (zend_long )) == FAILURE ) {
1450
+ zend_throw_exception (spl_ce_RuntimeException , "Random number generate failed" , 0 );
1451
+ RETURN_THROWS ();
1452
+ }
1453
+ }
1454
+
1430
1455
engine -> algo -> seed (engine -> state , seed );
1431
1456
}
1432
1457
/* }}} */
@@ -1438,28 +1463,39 @@ PHP_METHOD(Random_Engine_XorShift128Plus, __construct)
1438
1463
php_random_engine_state_xorshift128plus * state = engine -> state ;
1439
1464
zend_string * str_seed = NULL ;
1440
1465
zend_long int_seed = 0 ;
1466
+ bool seed_is_null = true;
1441
1467
int i , j ;
1442
1468
1443
- ZEND_PARSE_PARAMETERS_START (1 , 1 )
1444
- Z_PARAM_STR_OR_LONG (str_seed , int_seed )
1469
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
1470
+ Z_PARAM_OPTIONAL ;
1471
+ Z_PARAM_STR_OR_LONG_OR_NULL (str_seed , int_seed , seed_is_null );
1445
1472
ZEND_PARSE_PARAMETERS_END ();
1446
-
1447
- if (str_seed ) {
1448
- /* char (8 bit) * 16 = 128 bits */
1449
- if (str_seed -> len == 16 ) {
1450
- /* Endianness safe copy */
1451
- for (i = 0 ; i < 2 ; i ++ ) {
1452
- state -> s [i ] = 0 ;
1453
- for (j = 0 ; j < 8 ; j ++ ) {
1454
- state -> s [i ] += ((uint64_t ) (unsigned char ) ZSTR_VAL (str_seed )[(i * 8 ) + j ]) << (j * 8 );
1455
- }
1473
+
1474
+ if (seed_is_null ) {
1475
+ for (i = 0 ; i < 2 ; i ++ ) {
1476
+ if (php_random_bytes_silent (& state -> s [i ], sizeof (uint64_t )) == FAILURE ) {
1477
+ zend_throw_exception (spl_ce_RuntimeException , "Random number generate failed" , 0 );
1478
+ RETURN_THROWS ();
1456
1479
}
1457
- } else {
1458
- zend_argument_value_error (1 , "state strings must be 16 bytes" );
1459
- RETURN_THROWS ();
1460
1480
}
1461
1481
} else {
1462
- engine -> algo -> seed (state , int_seed );
1482
+ if (str_seed ) {
1483
+ /* char (8 bit) * 16 = 128 bits */
1484
+ if (str_seed -> len == 16 ) {
1485
+ /* Endianness safe copy */
1486
+ for (i = 0 ; i < 2 ; i ++ ) {
1487
+ state -> s [i ] = 0 ;
1488
+ for (j = 0 ; j < 8 ; j ++ ) {
1489
+ state -> s [i ] += ((uint64_t ) (unsigned char ) ZSTR_VAL (str_seed )[(i * 8 ) + j ]) << (j * 8 );
1490
+ }
1491
+ }
1492
+ } else {
1493
+ zend_argument_value_error (1 , "state strings must be 16 bytes" );
1494
+ RETURN_THROWS ();
1495
+ }
1496
+ } else {
1497
+ engine -> algo -> seed (state , int_seed );
1498
+ }
1463
1499
}
1464
1500
}
1465
1501
/* }}} */
@@ -1497,28 +1533,39 @@ PHP_METHOD(Random_Engine_Xoshiro256StarStar, __construct)
1497
1533
php_random_engine_state_xoshiro256starstar * state = engine -> state ;
1498
1534
zend_string * str_seed = NULL ;
1499
1535
zend_long int_seed = 0 ;
1536
+ bool seed_is_null = true;
1500
1537
int i , j ;
1501
1538
1502
- ZEND_PARSE_PARAMETERS_START (1 , 1 )
1503
- Z_PARAM_STR_OR_LONG (str_seed , int_seed )
1539
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
1540
+ Z_PARAM_OPTIONAL ;
1541
+ Z_PARAM_STR_OR_LONG_OR_NULL (str_seed , int_seed , seed_is_null );
1504
1542
ZEND_PARSE_PARAMETERS_END ();
1505
1543
1506
- if (str_seed ) {
1507
- /* char (8 bit) * 32 = 256 bits */
1508
- if (str_seed -> len == 32 ) {
1509
- /* Endianness safe copy */
1510
- for (i = 0 ; i < 4 ; i ++ ) {
1511
- state -> s [i ] = 0 ;
1512
- for (j = 0 ; j < 8 ; j ++ ) {
1513
- state -> s [i ] += ((uint64_t ) (unsigned char ) ZSTR_VAL (str_seed )[(i * 8 ) + j ]) << (j * 8 );
1514
- }
1544
+ if (seed_is_null ) {
1545
+ for (i = 0 ; i < 4 ; i ++ ) {
1546
+ if (php_random_bytes_silent (& state -> s [i ], sizeof (uint64_t )) == FAILURE ) {
1547
+ zend_throw_exception (spl_ce_RuntimeException , "Random number generate failed" , 0 );
1548
+ RETURN_THROWS ();
1515
1549
}
1516
- } else {
1517
- zend_argument_value_error (1 , "state strings must be 32 bytes" );
1518
- RETURN_THROWS ();
1519
1550
}
1520
1551
} else {
1521
- engine -> algo -> seed (state , int_seed );
1552
+ if (str_seed ) {
1553
+ /* char (8 bit) * 32 = 256 bits */
1554
+ if (str_seed -> len == 32 ) {
1555
+ /* Endianness safe copy */
1556
+ for (i = 0 ; i < 4 ; i ++ ) {
1557
+ state -> s [i ] = 0 ;
1558
+ for (j = 0 ; j < 8 ; j ++ ) {
1559
+ state -> s [i ] += ((uint64_t ) (unsigned char ) ZSTR_VAL (str_seed )[(i * 8 ) + j ]) << (j * 8 );
1560
+ }
1561
+ }
1562
+ } else {
1563
+ zend_argument_value_error (1 , "state strings must be 32 bytes" );
1564
+ RETURN_THROWS ();
1565
+ }
1566
+ } else {
1567
+ engine -> algo -> seed (state , int_seed );
1568
+ }
1522
1569
}
1523
1570
}
1524
1571
/* }}} */
@@ -1536,7 +1583,7 @@ PHP_METHOD(Random_Engine_Xoshiro256StarStar, jump)
1536
1583
1537
1584
for (i = 0 ; i < sizeof (jmp ) / sizeof (* jmp ); i ++ ) {
1538
1585
for (j = 0 ; j < 64 ; j ++ ) {
1539
- if (jmp [i ] & UINT64_C ( 1 ) << j ) {
1586
+ if (jmp [i ] & 1ULL << j ) {
1540
1587
s0 ^= s -> s [0 ];
1541
1588
s1 ^= s -> s [1 ];
1542
1589
s2 ^= s -> s [2 ];
@@ -1599,11 +1646,6 @@ PHP_METHOD(Random_Randomizer, __construct)
1599
1646
/* Create default RNG instance */
1600
1647
if (!engine_object ) {
1601
1648
engine_object = php_random_engine_secure_new (random_ce_Random_Engine_Secure );
1602
- zend_call_known_instance_method_with_0_params (
1603
- random_ce_Random_Engine_Secure -> constructor ,
1604
- engine_object ,
1605
- NULL
1606
- );
1607
1649
1608
1650
/* No need self-refcount */
1609
1651
GC_DELREF (engine_object );
0 commit comments