Skip to content

Commit ac8bd68

Browse files
committed
split interfaces, add jump
1 parent 00e285a commit ac8bd68

File tree

4 files changed

+217
-35
lines changed

4 files changed

+217
-35
lines changed

ext/random/php_random.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ extern zend_module_entry random_module_entry;
126126
# define phpext_random_ptr &random_module_entry
127127

128128
extern PHPAPI zend_class_entry *random_ce_Random_Engine;
129+
extern PHPAPI zend_class_entry *random_ce_Random_CryptoSafeEngine;
130+
extern PHPAPI zend_class_entry *random_ce_Random_SeedableEngine;
131+
extern PHPAPI zend_class_entry *random_ce_Random_SerializableEngine;
132+
129133
extern PHPAPI zend_class_entry *random_ce_Random_Engine_CombinedLCG;
130134
extern PHPAPI zend_class_entry *random_ce_Random_Engine_MersenneTwister;
131135
extern PHPAPI zend_class_entry *random_ce_Random_Engine_Secure;

ext/random/random.c

Lines changed: 104 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@
145145
ZEND_DECLARE_MODULE_GLOBALS(random)
146146

147147
PHPAPI zend_class_entry *random_ce_Random_Engine;
148+
PHPAPI zend_class_entry *random_ce_Random_CryptoSafeEngine;
149+
PHPAPI zend_class_entry *random_ce_Random_SeedableEngine;
150+
PHPAPI zend_class_entry *random_ce_Random_SerializableEngine;
151+
148152
PHPAPI zend_class_entry *random_ce_Random_Engine_CombinedLCG;
149153
PHPAPI zend_class_entry *random_ce_Random_Engine_MersenneTwister;
150154
PHPAPI zend_class_entry *random_ce_Random_Engine_Secure;
@@ -1403,13 +1407,6 @@ PHP_METHOD(Random_Engine_MersenneTwister, __construct)
14031407
}
14041408
/* }}} */
14051409

1406-
/* {{{ Construct object */
1407-
PHP_METHOD(Random_Engine_Secure, __construct)
1408-
{
1409-
ZEND_PARSE_PARAMETERS_NONE();
1410-
}
1411-
/* }}} */
1412-
14131410
/* {{{ Construct object */
14141411
PHP_METHOD(Random_Engine_XorShift128Plus, __construct)
14151412
{
@@ -1443,6 +1440,32 @@ PHP_METHOD(Random_Engine_XorShift128Plus, __construct)
14431440
}
14441441
/* }}} */
14451442

1443+
/* {{{ Jump a state */
1444+
PHP_METHOD(Random_Engine_XorShift128Plus, jump)
1445+
{
1446+
php_random_engine *engine = Z_RANDOM_ENGINE_P(ZEND_THIS);
1447+
php_random_engine_state_xorshift128plus *s = (php_random_engine_state_xorshift128plus *) engine->state;
1448+
static const uint64_t jmp[] = { 0x8a5cd789635d2dff, 0x121fd2155c472f96 };
1449+
uint64_t s0 = 0, s1 = 0;
1450+
int i, j;
1451+
1452+
ZEND_PARSE_PARAMETERS_NONE();
1453+
1454+
for (i = 0; i < sizeof (jmp) / sizeof (*jmp); i++) {
1455+
for (j = 0; j < 64; j++) {
1456+
if (jmp[i] & UINT64_C(1) << j) {
1457+
s0 ^= s->s[0];
1458+
s1 ^= s->s[1];
1459+
}
1460+
engine->algo->generate(engine->state);
1461+
}
1462+
}
1463+
1464+
s->s[0] = s0;
1465+
s->s[1] = s1;
1466+
}
1467+
/* }}} */
1468+
14461469
/* {{{ Construct object */
14471470
PHP_METHOD(Random_Engine_Xoshiro256StarStar, __construct)
14481471
{
@@ -1476,6 +1499,66 @@ PHP_METHOD(Random_Engine_Xoshiro256StarStar, __construct)
14761499
}
14771500
/* }}} */
14781501

1502+
/* {{{ Jump a state */
1503+
PHP_METHOD(Random_Engine_Xoshiro256StarStar, jump)
1504+
{
1505+
php_random_engine *engine = Z_RANDOM_ENGINE_P(ZEND_THIS);
1506+
php_random_engine_state_xoshiro256starstar *s = (php_random_engine_state_xoshiro256starstar *) engine->state;
1507+
static const uint64_t jmp[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
1508+
uint64_t s0 = 0, s1 = 0, s2 = 0, s3 = 0;
1509+
int i, j;
1510+
1511+
ZEND_PARSE_PARAMETERS_NONE();
1512+
1513+
for (i = 0; i < sizeof(jmp) / sizeof(*jmp); i++) {
1514+
for (j = 0; j < 64; j++) {
1515+
if (jmp[i] & UINT64_C(1) << j) {
1516+
s0 ^= s->s[0];
1517+
s1 ^= s->s[1];
1518+
s2 ^= s->s[2];
1519+
s3 ^= s->s[3];
1520+
}
1521+
engine->algo->generate(engine->state);
1522+
}
1523+
}
1524+
1525+
s->s[0] = s0;
1526+
s->s[1] = s1;
1527+
s->s[2] = s2;
1528+
s->s[3] = s3;
1529+
}
1530+
/* }}} */
1531+
1532+
/* {{{ Jump a long state */
1533+
PHP_METHOD(Random_Engine_Xoshiro256StarStar, jumpLong)
1534+
{
1535+
php_random_engine *engine = Z_RANDOM_ENGINE_P(ZEND_THIS);
1536+
php_random_engine_state_xoshiro256starstar *s = (php_random_engine_state_xoshiro256starstar *) engine->state;
1537+
static const uint64_t jmp[] = { 0x76e15d3efefdcbbf, 0xc5004e441c522fb3, 0x77710069854ee241, 0x39109bb02acbe635 };
1538+
uint64_t s0 = 0, s1 = 0, s2 = 0, s3 = 0;
1539+
int i, j;
1540+
1541+
ZEND_PARSE_PARAMETERS_NONE();
1542+
1543+
for (i = 0; i < sizeof(jmp) / sizeof(*jmp); i++) {
1544+
for (j = 0; j < 64; j++) {
1545+
if (jmp[i] & UINT64_C(1) << j) {
1546+
s0 ^= s->s[0];
1547+
s1 ^= s->s[1];
1548+
s2 ^= s->s[2];
1549+
s3 ^= s->s[3];
1550+
}
1551+
engine->algo->generate(engine->state);
1552+
}
1553+
}
1554+
1555+
s->s[0] = s0;
1556+
s->s[1] = s1;
1557+
s->s[2] = s2;
1558+
s->s[3] = s3;
1559+
}
1560+
/* }}} */
1561+
14791562
/* {{{ Construct object */
14801563
PHP_METHOD(Random_Randomizer, __construct)
14811564
{
@@ -1664,40 +1747,49 @@ PHP_MINIT_FUNCTION(random)
16641747
/* Random\Engine */
16651748
random_ce_Random_Engine = register_class_Random_Engine();
16661749

1750+
/* Random\CryptoSafeEngine */
1751+
random_ce_Random_CryptoSafeEngine = register_class_Random_CryptoSafeEngine(random_ce_Random_Engine);
1752+
1753+
/* Random\SeedableEngine */
1754+
random_ce_Random_SeedableEngine = register_class_Random_SeedableEngine(random_ce_Random_Engine);
1755+
1756+
/* Random\SerializableEngine */
1757+
random_ce_Random_SerializableEngine = register_class_Random_SerializableEngine(random_ce_Random_Engine);
1758+
16671759
/* Random\Engine\CombinedLCG */
1668-
random_ce_Random_Engine_CombinedLCG = register_class_Random_Engine_CombinedLCG(random_ce_Random_Engine);
1760+
random_ce_Random_Engine_CombinedLCG = register_class_Random_Engine_CombinedLCG(random_ce_Random_SeedableEngine, random_ce_Random_SerializableEngine);
16691761
random_ce_Random_Engine_CombinedLCG->create_object = php_random_engine_combinedlcg_new;
16701762
memcpy(&random_engine_combinedlcg_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
16711763
random_engine_combinedlcg_object_handlers.offset = XtOffsetOf(php_random_engine, std);
16721764
random_engine_combinedlcg_object_handlers.free_obj = php_random_engine_common_free_obj;
16731765
random_engine_combinedlcg_object_handlers.clone_obj = php_random_engine_common_clone_obj;
16741766

16751767
/* Random\Engine\MersenneTwister */
1676-
random_ce_Random_Engine_MersenneTwister = register_class_Random_Engine_MersenneTwister(random_ce_Random_Engine);
1768+
random_ce_Random_Engine_MersenneTwister = register_class_Random_Engine_MersenneTwister(random_ce_Random_SeedableEngine, random_ce_Random_SerializableEngine);
16771769
random_ce_Random_Engine_MersenneTwister->create_object = php_random_engine_mersennetwister_new;
16781770
memcpy(&random_engine_mersennetwister_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
16791771
random_engine_mersennetwister_object_handlers.offset = XtOffsetOf(php_random_engine, std);
16801772
random_engine_mersennetwister_object_handlers.free_obj = php_random_engine_common_free_obj;
16811773
random_engine_mersennetwister_object_handlers.clone_obj = php_random_engine_common_clone_obj;
16821774

16831775
/* Random\Engine\Secure */
1684-
random_ce_Random_Engine_Secure = register_class_Random_Engine_Secure(random_ce_Random_Engine);
1776+
random_ce_Random_Engine_Secure = register_class_Random_Engine_Secure(random_ce_Random_CryptoSafeEngine);
16851777
random_ce_Random_Engine_Secure->create_object = php_random_engine_secure_new;
16861778
memcpy(&random_engine_secure_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
16871779
random_engine_secure_object_handlers.offset = XtOffsetOf(php_random_engine, std);
16881780
random_engine_secure_object_handlers.free_obj = php_random_engine_common_free_obj;
16891781
random_engine_secure_object_handlers.clone_obj = NULL;
16901782

16911783
/* Random\Engine\XorShift128Plus */
1692-
random_ce_Random_Engine_XorShift128Plus = register_class_Random_Engine_XorShift128Plus(random_ce_Random_Engine);
1784+
random_ce_Random_Engine_XorShift128Plus = register_class_Random_Engine_XorShift128Plus(random_ce_Random_SeedableEngine, random_ce_Random_SerializableEngine);
16931785
random_ce_Random_Engine_XorShift128Plus->create_object = php_random_engine_xorshift128plus_new;
16941786
memcpy(&random_engine_xorshift128plus_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
16951787
random_engine_xorshift128plus_object_handlers.offset = XtOffsetOf(php_random_engine, std);
16961788
random_engine_xorshift128plus_object_handlers.free_obj = php_random_engine_common_free_obj;
16971789
random_engine_xorshift128plus_object_handlers.clone_obj = php_random_engine_common_clone_obj;
16981790

16991791
/* Random\Engine\Xoshiro256StarStar */
1700-
random_ce_Random_Engine_Xoshiro256StarStar = register_class_Random_Engine_Xoshiro256StarStar(random_ce_Random_Engine);
1792+
random_ce_Random_Engine_Xoshiro256StarStar = register_class_Random_Engine_Xoshiro256StarStar(random_ce_Random_SeedableEngine, random_ce_Random_SerializableEngine);
17011793
random_ce_Random_Engine_Xoshiro256StarStar->create_object = php_random_engine_xoshiro256starstar_new;
17021794
memcpy(&random_engine_xoshiro256starstar_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
17031795
random_engine_xoshiro256starstar_object_handlers.offset = XtOffsetOf(php_random_engine, std);

ext/random/random.stub.php

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function random_int(int $min, int $max): int {}
2727

2828
namespace Random\Engine
2929
{
30-
class CombinedLCG implements Random\Engine
30+
class CombinedLCG implements Random\SeedableEngine, Random\SerializableEngine
3131
{
3232
public function __construct(int $seed) {}
3333

@@ -40,7 +40,7 @@ public function __unserialize(array $data): void {}
4040
public function __debugInfo(): array {}
4141
}
4242

43-
class MersenneTwister implements Random\Engine
43+
class MersenneTwister implements Random\SeedableEngine, Random\SerializableEngine
4444
{
4545
public function __construct(int $seed, int $mode = MT_RAND_MT19937) {}
4646

@@ -58,21 +58,21 @@ public function __debugInfo(): array {}
5858
}
5959

6060
/** @not-serializable */
61-
class Secure implements Random\Engine
61+
class Secure implements Random\CryptoSafeEngine
6262
{
63-
public function __construct() {}
64-
6563
/** @implementation-alias Random\Engine\CombinedLCG::generate */
6664
public function generate(): string {}
6765
}
6866

69-
class XorShift128Plus implements Random\Engine
67+
class XorShift128Plus implements Random\SeedableEngine, Random\SerializableEngine
7068
{
7169
public function __construct(string|int $seed) {}
7270

7371
/** @implementation-alias Random\Engine\CombinedLCG::generate */
7472
public function generate(): string {}
7573

74+
public function jump(): void {}
75+
7676
/** @implementation-alias Random\Engine\CombinedLCG::__serialize */
7777
public function __serialize(): array {}
7878

@@ -83,13 +83,17 @@ public function __unserialize(array $data): void {}
8383
public function __debugInfo(): array {}
8484
}
8585

86-
class Xoshiro256StarStar implements Random\Engine
86+
class Xoshiro256StarStar implements Random\SeedableEngine, Random\SerializableEngine
8787
{
8888
public function __construct(string|int $seed) {}
8989

9090
/** @implementation-alias Random\Engine\CombinedLCG::generate */
9191
public function generate(): string {}
9292

93+
public function jump(): void {}
94+
95+
public function jumpLong(): void {}
96+
9397
/** @implementation-alias Random\Engine\CombinedLCG::__serialize */
9498
public function __serialize(): array {}
9599

@@ -108,6 +112,23 @@ interface Engine
108112
public function generate(): string;
109113
}
110114

115+
interface CryptoSafeEngine extends Engine
116+
{
117+
}
118+
119+
interface SeedableEngine extends Engine
120+
{
121+
}
122+
123+
interface SerializableEngine extends Engine
124+
{
125+
public function __serialize(): array {}
126+
127+
public function __unserialize(array $data): void {}
128+
129+
public function __debugInfo(): array {}
130+
}
131+
111132
final class Randomizer
112133
{
113134
public readonly Engine $engine;

0 commit comments

Comments
 (0)