Lair Of The Multimedia Guru


How correlated is pcg-dxsm output?

Correlations based on the lower half of the LCG

Lets try picking some correlated combinations with (using my very simple pcg-dxsm implementation)

Multiplier 15750249268501108917 15750249268501108917 15750249268501108917
Increment 123456789 15750249268624565705 31500498537125674621
Seed 31415 31414 31413
Output 1 0x563B0DB76F45EEC2 0xDEE2CC4990CDBE1E 0xDEE2CC4990CDBE1E
Output 2 0x064C612B5E0A4853 0x064C612B5E0A4853 0x704228ECB09FC1D5
Output 3 0x4727428C93C1A285 0x5A7E3EA39E71C29F 0x5A7E3EA39E71C29F
Output 4 0x2745482D3BDBC1C0 0x2745482D3BDBC1C0 0x15D15980AE293340
Output 5 0x6055DF5FCE178AB2 0xC5DC9DC897A78F1E 0xC5DC9DC897A78F1E
Output 6 0x05DDF19C395C342F 0x05DDF19C395C342F 0x51705B299006C1C1
Output 7 0xD7AFDA4C1654626B 0x89A204161A53CA99 0x89A204161A53CA99
Output 8 0x2C1FCD6649DB8016 0x2C1FCD6649DB8016 0x338710EA7C027382
Output 9 0xEDE28080A228A6DC 0xED272B75717128A4 0xED272B75717128A4
Output 10 0xB05EFD2651E59BC7 0xB05EFD2651E59BC7 0x20911E0B5D6AE551
Output 11 0xD6045D380A566F2D 0xE6584BDE2C470387 0xE6584BDE2C470387
Output 12 0x1BF91549D870370F 0x1BF91549D870370F 0xF434399E25ED24B5
Output 13 0x1D9EB55CB071B60A 0x1DA3A160F1C93F66 0x1DA3A160F1C93F66
Output 14 0x892A16096BF94286 0x892A16096BF94286 0x8F5678078367E87A
Output 15 0xA7292EEE7AF4777F 0x281913D2D3F2DFC5 0x281913D2D3F2DFC5
Output 16 0x08AB29210A0B6FF1 0x08AB29210A0B6FF1 0xC0DD5B88BF6885A3
Output 17 0x20E581A9EA8BF155 0xB17BBB3957418DBB 0xB17BBB3957418DBB
Output 18 0x768E7BD7B5223C36 0x768E7BD7B5223C36 0x086B7F8F81A5CEDA
Output 19 0xF67313E1E5454A96 0xD3026BC096FEDDE2 0xD3026BC096FEDDE2
Output 20 0xAB091F6C4C169476 0xAB091F6C4C169476 0xF29E461BBD7C6952
Output 21 0xB18D1BC34F78E4D1 0x205033BF4C77D237 0x205033BF4C77D237
Output 22 0x5BBCD31929B10ED3 0x5BBCD31929B10ED3 0xFDCB8D05F8C862FD
Output 23 0xC64AFD5DFC7654A7 0x54C875057AAA9DCD 0x54C875057AAA9DCD
Output 24 0x34866A3DF2054E13 0x34866A3DF2054E13 0x4C9D903AB9738D79
Output 25 0x29CA92D156E93DD4 0x1174B427B597C82C 0x1174B427B597C82C
Output 26 0x46B0D6BFFE3BD1C3 0x46B0D6BFFE3BD1C3 0x18A4BCCC15242755
Output 27 0x74DF62C8A26F65CD 0xF5CAC48CFC7B4D47 0xF5CAC48CFC7B4D47
Output 28 0xE737155A33FC916F 0xE737155A33FC916F 0x2A8E83BF16B3C6F5
Output 29 0x0E0E87DB2724235B 0x82EA039F9945EE0D 0x82EA039F9945EE0D
Output 30 0x2367AB4D5FA3ABBE 0x2367AB4D5FA3ABBE 0x274FC0D71A60FF82

Besides the exactly equal ones, the more careful reader will have noticed that each line either has even or odd entries, so the 3 seed/increment pairs generate equal results in the lowest bit.

You might ask why does this all happen? Well, the identical numbers happen because the lowest bit is ored away in DXSM, that is forced to be 1. So any cases differing only by that bit at the LCG stage become identical in later stages. The other similarities happen because the mixing isnt as good as it needs to be to remove all differences from very similar input and LCGs can produce such very similar input when one picks the “wrong” parameters.

Did i hand pick the worst ? Is that the only case ?
lets see

Multiplier 15750249268501108917 15750249268501108917
Increment 123456789 1134925067785824341058664979018534165
Seed 31415 340282366920938463463302549837730314935
0x56 3B0DB76F45EEC2 0x04 3B0DB76F45EEC2
0x06 4C612B5E0A4853 0xC7 4C612B5E0A4853
0x47 27428C93C1A285 0x54 27428C93C1A285
0x27 45482D3BDBC1C0 0xE7 45482D3BDBC1C0
0x60 55DF5FCE178AB2 0x96 55DF5FCE178AB2
0x05 DDF19C395C342F 0xCE DDF19C395C342F
0xD7 AFDA4C1654626B 0xEE AFDA4C1654626B
0x2C 1FCD6649DB8016 0xE2 1FCD6649DB8016
0xED E28080A228A6DC 0xD1 E28080A228A6DC
0xB0 5EFD2651E59BC7 0x75 5EFD2651E59BC7
0xD6 045D380A566F2D 0x03 045D380A566F2D
0x1B F91549D870370F 0xEE F91549D870370F
0x1D 9EB55CB071B60A 0xCB 9EB55CB071B60A
0x89 2A16096BF94286 0x83 2A16096BF94286
0xA7 292EEE7AF4777F 0xCA 292EEE7AF4777F
0x08 AB29210A0B6FF1 0xE1 AB29210A0B6FF1
0x20 E581A9EA8BF155 0x53 E581A9EA8BF155
0x76 8E7BD7B5223C36 0xC8 8E7BD7B5223C36
0xF6 7313E1E5454A96 0x9C 7313E1E5454A96
0xAB 091F6C4C169476 0x19 091F6C4C169476
0xB1 8D1BC34F78E4D1 0x64 8D1BC34F78E4D1
0x5B BCD31929B10ED3 0x70 BCD31929B10ED3
0xC6 4AFD5DFC7654A7 0x59 4AFD5DFC7654A7
0x34 866A3DF2054E13 0xE7 866A3DF2054E13
0x29 CA92D156E93DD4 0x55 CA92D156E93DD4
0x46 B0D6BFFE3BD1C3 0x0F B0D6BFFE3BD1C3
0x74 DF62C8A26F65CD 0x31 DF62C8A26F65CD
0xE7 37155A33FC916F 0xAA 37155A33FC916F
0x0E 0E87DB2724235B 0x67 0E87DB2724235B
0x23 67AB4D5FA3ABBE 0x05 67AB4D5FA3ABBE

Here 7 out of 8 bytes match apparently for each. Is that the worst ? no we could make part of the first byte match too, it just becomes harder to color the table to match that.

Correlations based on the upper half of the LCG

Update 2024-03-02, After thynson noticed that the above 2 classes of correlations, all have multiplier-1 as a coresidual of the increment. Ive looked more and found more classes of correlations.
The above 2 cases produce correlations because they introduce 2 specific classes of differences in the lower half of the underlying LCG, we can also introduce other specific differences in the upper half to create correlations. I first thought the mixing stage would make this difficult, but it doesnt seem that difficult.

Multiplier 15750249268501108917 15750249268501108917 15750249268501108917 15750249268501108917
Increment 123456789 188175727042032768542098945617541451029 94087863521016384271049472808832453909 94087863521016384271049472808832453909
Seed 31415 170141183500083312988819472512656112311 85070591750041656494409736256328071863 255211775210510888226097039972212177591
Output1 0x563B0DB76F45E EC2 0x4EAC9CA5AB826 EC2 0x5273D52E8D642 EC2 0x8BA757339BF3B 0C4
Output2 0x064C612B5E0A4 853 0x507FC7CA7B00C 853 0x7CF75FC4DBFEB B3C 0x6132ADDBCF8F0 853
Output3 0x4727428C93C1A 285 0xE8681791D88ED 60B 0x821B65AAAE9D3 074 0x56EBE12BED519 60B
Output4 0x2745482D3BDBC 1C0 0x7D02EE9F8B954 1C0 0x7C6674F413FF0 1C0 0x064DB7AF79614 8E3
Output5 0x6055DF5FCE178 AB2 0x5284D85445650 AB2 0xCB9C54CE810BC AB2 0x89BF5C086BDE9 447
Output6 0x05DDF19C395C3 42F 0xDA6CAC69AB735 98E 0x979601E7DBD3B 9D1 0x41C4B15A978E7 42F
Output7 0xD7AFDA4C16546 26B 0xD22DEF5B1E600 21E 0x81EE59290B934 21E 0xED6327A2A5747 2A1
Output8 0x2C1FCD6649DB8 016 0x3CD4A9AF3862F 39A 0x12F825A58C46C 679 0x798CE3702E873 39A
Output9 0xEDE28080A228A 6DC 0x8443929D63A67 C1C 0x02CE2330E2663 F1F 0xE422EEFF6C846 6DC
Output10 0xB05EFD2651E59 BC7 0x5BB46EBB794BC 378 0x9EC419F1B9850 378 0x3DD8F2BA415FE 2CE
Output11 0xD6045D380A566 F2D 0x909115D376D6E F2D 0xB34AB985C096A F2D 0xA49969ED9AE37 EBF
Output12 0x1BF91549D8703 70F 0x8B81A72468CE6 2BB 0x05043537DB072 5E2 0x20046693FD23A 2BB
Output13 0x1D9EB55CB071B 60A 0x264C5A17BA703 60A 0x458D7586D42BD 7B7 0x21F587BA3570F 60A
Output14 0x892A16096BF94 286 0x97EA766824D8C 286 0x908A4638C8690 286 0x8B8230900DC31 894
Output15 0xA7292EEE7AF47 77F 0x45B865A22102D 671 0xED910677E00EA 244 0xB9F1AF9C302C3 77F
Output16 0x08AB29210A0B6 FF1 0x66F131DB875BA 123 0xF5F9A395C5C1A FF1 0x035C3B9F6264E A8C
Output17 0x20E581A9EA8BF 155 0x2B7CBD378A1FB 44A 0x835FF11C3FF63 155 0xD6C0C0A58FD86 96A
Output18 0x768E7BD7B5223 C36 0x8282FAEF4390B C36 0x7C88BB637C597 C36 0x4E30CF973257E 263
Output19 0xF67313E1E5454 A96 0xBCADB3276FBCA D92 0x6A4F6314C50F9 11D 0x0DCC176A07468 A96
Output20 0xAB091F6C4C169 476 0x7C6C880401881 476 0x651E3C4FDC40D 476 0x87103D0FEAEBB 5A9
Output21 0xB18D1BC34F78E 4D1 0x182EF712B7CC9 6ED 0x632712BFD8439 536 0x7D1586E9295E2 4D1
Output22 0x5BBCD31929B10 ED3 0x177CCDEF531D3 167 0xC86CF8BD98EEF 167 0x6A7959BA3EC3B 1E5
Output23 0xC64AFD5DFC765 4A7 0xDBFE7B848484D 4A7 0x5124BC71407D9 4A7 0x7317F810CA105 929
Output24 0x34866A3DF2054 E13 0x2B7F37E87E70E BA7 0x87E4C62AA01E0 E13 0xA9077B94F6670 644
Output25 0x29CA92D156E93 DD4 0x3AE2C3E7ABF63 199 0xBCF4EEF02BA57 199 0x190804CAE2166 D48
Output26 0x46B0D6BFFE3BD 1C3 0x714BB6B1E3FC4 96F 0x5E459BFFC60D8 F95 0xB9A7262288870 96F
Output27 0x74DF62C8A26F6 5CD 0x25B37CDE46C28 A09 0x4111E2836E4B0 090 0x01289C6FC845C A09
Output28 0xE737155A33FC9 16F 0x8CB957BC0E0A1 16F 0xAEB26C1EB1942 EC4 0x1475F42946F5D 16F
Output29 0x0E0E87DB27242 35B 0xF94895647AA13 EF5 0xCA2ACE10F845E 35B 0x5234DF04DB0C2 7DE
Output30 0x2367AB4D5FA3A BBE 0x56F8654413BC2 BBE 0xE69CD0B7EE3B4 D08 0x899F4E5205976 BBE

Above attacks the first stage of the mixer, we can also attack the 2nd stage, it looks less impressive but none the less instead of 1 identical byte in 256 we see alot more

Multiplier 15750249268501108917 15750249268501108917 15750249268501108917
Increment 123456789 271162317658692578196538916254707862805 152861171144907760414978380921711611157
Seed 31415 39621334812049856571820243639 9905333703012464142955084471
Output1 0x563B0DB76F45EE C2 0x0083130D590C82 C2 0x56399A48F66C29 C2
Output2 0x064C612B5E0A48 53 0xAFFAF7C625B7A0 55 0x426A227A69AC8B 55
Output3 0x4727428C93C1A2 85 0x3BFE265FC469DD 34 0xDF23B38901C67B 5C
Output4 0x2745482D3BDBC1 C0 0x28B8CF040CE59E 23 0xF2C12F43D3C5BC 98
Output5 0x6055DF5FCE178A B2 0xEB4BAAA8C260D7 AD 0x52224A76A9AB37 DF
Output6 0x05DDF19C395C34 2F 0xD65E464613ADA6 A2 0xCF042916ADA3DB F9
Output7 0xD7AFDA4C165462 6B 0x9FE6DE769FFF8E 1E 0xB816350D4D04B3 1E
Output8 0x2C1FCD6649DB80 16 0x754DC19986C65F 9A 0xCFC556D81AB400 D2
Output9 0xEDE28080A228A6 DC 0xD249BACC4FF71F 15 0xC03E7BF3E7423B A8
Output10 0xB05EFD2651E59B C7 0x794EA34DECBCC4 B4 0x9448CB72344E34 D5
Output11 0xD6045D380A566F 2D 0x2BB1BB3BA4DDCF 4A 0xC2956A532B866C AB
Output12 0x1BF91549D87037 0F 0x8483638585B29A C1 0xE085893BCA2906 D5
Output13 0x1D9EB55CB071B6 0A 0xB54C78D8826582 0A 0x11B567A953D0E2 2F
Output14 0x892A16096BF942 86 0x073360B2311E2E 86 0x0DD1F9F1A63F27 80
Output15 0xA7292EEE7AF477 7F 0x47C425E350061C EF 0x06263999BE6442 AE
Output16 0x08AB29210A0B6F F1 0xB6894B4E36C7FD 52 0xD38C235183235A F9
Output17 0x20E581A9EA8BF1 55 0x08854CD5C6D98B F9 0x0CD106F83B232A 55
Output18 0x768E7BD7B5223C 36 0xA1DDA8C4BE25F5 25 0xD0B32BB399C62F 36
Output19 0xF67313E1E5454A 96 0xCEFA2E1F1711E0 59 0x31AF5438CE9EA2 5F
Output20 0xAB091F6C4C1694 76 0x67110439B8E660 76 0x5FD39652AC17B6 A9
Output21 0xB18D1BC34F78E4 D1 0xBB66DD962205EA F1 0x4BE1680D18C928 B1
Output22 0x5BBCD31929B10E D3 0xFC0D37393C8893 EA 0xEB5BAA64A129E1 D3
Output23 0xC64AFD5DFC7654 A7 0x87EC987780AF59 FA 0xB31BA2E5123C18 CF
Output24 0x34866A3DF2054E 13 0xDB102ADD9EA7D7 0A 0x8885FA71C030D2 E7
Output25 0x29CA92D156E93D D4 0xDCDD9AA636484C 7A 0xDD95314A5E5CA0 8D
Output26 0x46B0D6BFFE3BD1 C3 0x1669656599FB38 9E 0xF0C25ACE4573A6 35
Output27 0x74DF62C8A26F65 CD 0x72DFFFE5F48C19 5B 0xC494B0FF934BE3 46
Output28 0xE737155A33FC91 6F 0xBE560D45FF9E8B C9 0x2D8821EB759B1F 50
Output29 0x0E0E87DB272423 5B 0xCB29008A08DC1A DC 0xD712484F90D6E4 72
Output30 0x2367AB4D5FA3AB BE 0x58E6BE59AE99D8 4B 0x7C289593C90335 F1

We can also use this to generate more than 8bit matches, but they are spread out more so it doesnt show up nicely in the first 30 output values.
For example ./pcg-dxsm-64 15750249268501108917 164824157741578258584156320684186520853 3046549733826659956002159287 1000000 16 and ./pcg-dxsm-64 15750249268501108917 123456789 31415 1000000 16 produce a million values, we expect the low 20 bits to match in one case in a million on average but these have over a thousand such matches

Update 2024-03-03: Verifying that our PCG64-DXSM implementation is correct

./pcg-dxsm-64  15750249268501108917 123456789 31415 10 10

from randomgen import PCG64
g = PCG64(2**128+31415-123456789,123456788/2,variant="dxsm",mode="legacy"); 
for i in range(10): print(g.random_raw())

Update 2024-03-04: Add correlations with equal seeds

Correlations with equal seeds

For the case of equal seeds it must be first said that different pcg64-dxsm implementations mangle the seed in different ways. Thus whats equal in one is not equal in another. We show examples of equal seeds at the LCG level first, this is how the previous examples defined the seed.

Multiplier 15750249268501108917 15750249268501108917
Increment 340282366920937968669293837469431615317 340282366920937968685044086737932724233
Seed 31415 31415
Output1 0x0000000000000000 0x0000000000000000
Output2 0x0000000000000000 0x5542869E099E356E
Output3 0xCA1A90080FC41D1A 0x7CC2BF122332851C
Output4 0x7CC2BF122332851C 0xCB8D59E2E4C1218A
Output5 0x443C52CD5384C766 0x4E16E6CE9CA5478E
Output6 0x4E16E6CE9CA5478E 0x79339B1DB09444E9
Output7 0x6F763957F4353DDB 0x10EE4E400E4F428E
Output8 0x10EE4E400E4F428E 0x5F9CFCB33A3A60EF
Output9 0x4418DDB3F1FE88B1 0x2B907893DCD59873
Output10 0x2B907893DCD59873 0xC984F2B06253372B
Output11 0xA38FA95F35AB6739 0x3E6AE114E83A3619
Output12 0x3E6AE114E83A3619 0x52946D7362EEAA86
Output13 0x0E4B57A85E8670EA 0x04769CEADA5CC799
Output14 0x04769CEADA5CC799 0x2E71EE38F3683F6C
Output15 0xED4F32C1AF264384 0x54C64408D6FABE08
Output16 0x54C64408D6FABE08 0x6B65E69BB07E56F6
Output17 0xDAD0B79C5C6EFC2A 0xAB06E3184A632E04
Output18 0xAB06E3184A632E04 0x88E36EABEA546B63
Output19 0xE563E5FD7697D091 0x2709664DC434EDE3
Output20 0x2709664DC434EDE3 0x6277238F88A1D8D6
Output21 0x74B88A9EDBCF94FA 0xF4B4B8A667253240
Output22 0xF4B4B8A667253240 0x2B0DF01AF7F68886
Output23 0x23906462E660A212 0x9591B3C5A81F1E01
Output24 0x9591B3C5A81F1E01 0x5A67803048FA88EC
Output25 0x8C3FDB1C4F568714 0xEA48F0F9B2EE760B
Output26 0xEA48F0F9B2EE760B 0xA5785DE15372C0A0
Output27 0x6FB95CE223AFFEE0 0xE7F4EEB0FD473A91
Output28 0xE7F4EEB0FD473A91 0x83886CE76BF8FCDA
Output29 0xAE3D319DFBE64AF6 0xEBA429DA1AF5EE38
Output30 0xEBA429DA1AF5EE38 0x2E10BCE8F08A03B7

And another example:

Multiplier 15750249268501108917 15750249268501108917
Increment 18158801084572694679761040473092597769 340282366920937968670446758974038462293
Seed 31415 31415
Output1 0x2 8C57634CF3ADEA3 0x0 000000000000000
Output2 0x4 5E72764CBAC7D8A 0x1 8C57634CF3ADEA3
Output3 0x0 9F5D8F29B240248 0x0 9804DEEE6EB9D0E
Output4 0x4 8BD93FA680EE36C 0x8 9F5D8F29B240248
Output5 0x8 F2CF0B4671A5D87 0x4 2B52509EB19E6B4
Output6 0xE 57EE9B1AB50A947 0x7 F2CF0B4671A5D87
Output7 0x6 E92305B0D002F61 0xE 02E81E3F013B2B5
Output8 0x2 D513919164C9F11 0x5 E92305B0D002F61
Output9 0x2 FCAB132E105A9F2 0x1 C902225001A774F
Output10 0x6 E8A48BD7E37EE0C 0xC FCAB132E105A9F2
Output11 0x9 A9240D1A1572F73 0x9 64DE7D8E859E804
Output12 0x6 EF0158EC1476E59 0x2 A9240D1A1572F73
Output13 0x9 34A4391489DB1D4 0x4 B66D2865E881D4F
Output14 0xB 634A42C2394888A 0xD 34A4391489DB1D4
Output15 0x8 E03CA0BB984E16B 0x5 5CC7B5271F792FE
Output16 0x5 5F6ACB2C66FDED7 0x5 E03CA0BB984E16B
Output17 0x5 CBEC3EC2C5C03DE 0x3 BF46F487533BDF9
Output18 0x7 C46F2BD428796EA 0xB CBEC3EC2C5C03DE
Output19 0x0 39A4A7C2A084281 0xA 6A3E2D52E24926E
Output20 0x8 1A17AD6D8142476 0xB 39A4A7C2A084281
Output21 0x1 9223A7740BACC82 0x3 5A8AF9350D8645A
Output22 0x8 8DCB82922B55F8E 0x3 9223A7740BACC82
Output23 0x2 FB541FDDC8E5A86 0xE DB016F19FE29D2A
Output24 0xC 61E8DBF6577A704 0xC FB541FDDC8E5A86
Output25 0x8 2733F8F3CD82976 0x8 05A2C8C4F2E88FC
Output26 0x5 5A5329E50934786 0x6 2733F8F3CD82976
Output27 0xA 342EF7724025501 0x2 EBD1F90D6ADC342
Output28 0x1 A8635E212C32A2D 0xD 342EF7724025501
Output29 0x3 F87E671A19911B2 0x1 2B4DEB4213B90C8
Output30 0x7 C8BAC3F018FD61D 0x5 F87E671A19911B2

Now python randomgen + numpy

from randomgen import PCG64
g = PCG64(31415,(310562926860152171542224643668532814649>>1),variant="dxsm",mode="legacy"); g2 = PCG64(31415,(310562926860152171526474394400031705733>>1),variant="dxsm",mode="legacy");
for i in range(30): print("0x" + format(g.random_raw(), "016X") + " 0x" + format(g2.random_raw(), "016X"))
Multiplier 15750249268501108917 15750249268501108917
Increment 310562926860152171526474394400031705733>>1 310562926860152171542224643668532814649>>1
Seed 31415 31415
Output1 0xEE846300E83A27DC 0x7256D1D22864FB31
Output2 0x62B36CDF71DD1743 0x1C2239BDA2F793C6
Output3 0x1C2239BDA2F793C6 0xA25FB4606E9F9955
Output4 0x2C21FF9FA58D879B 0xA90BC860E5BC5E65
Output5 0xA90BC860E5BC5E65 0xD9A217425A7117AF
Output6 0x9B802E5C51C811D5 0x31A30A053121F011
Output7 0x31A30A053121F011 0xDF91893796BE498C
Output8 0xB6F6FCF3CC23CF14 0x27FFF0C3DFDAE842
Output9 0x27FFF0C3DFDAE842 0x5653E5F3D78910B6
Output10 0x043FFA9868AB2B22 0xC77C03211C0201CE
Output11 0xC77C03211C0201CE 0x1A2DC56C688DBDE8
Output12 0x1F3C5871B8AA1618 0x0C12CBDC34DFABB0
Output13 0x0C12CBDC34DFABB0 0xDFD2D074C5127C15
Output14 0xC7FEC3AED543EDE7 0x127120DC1B75A20E
Output15 0x127120DC1B75A20E 0xAA580CD3C44B571D
Output16 0x800C8F5DBF2D5C4B 0xD0D231D10F85BB11
Output17 0xD0D231D10F85BB11 0xB433A15370448948
Output18 0xB678DA426A582A58 0x4E5DC360D27E4857
Output19 0x4E5DC360D27E4857 0x52B4BF17EE5FB665
Output20 0x91A4127B348A8BAB 0xAD7A55AF7A1E62B2
Output21 0xAD7A55AF7A1E62B2 0xAAE73D4A877AEB9E
Output22 0xE6F6BA90233BFF2A 0x537BA3170D10A98F
Output23 0x537BA3170D10A98F 0x71778DBD0A1F1858
Output24 0x22D07B79FDA625E8 0xE03DFB31EDF18C5A
Output25 0xE03DFB31EDF18C5A 0x610809577FF8326B
Output26 0x82BA957BB887F8A1 0x5C430AB7C74B61D9
Output27 0x5C430AB7C74B61D9 0x2C63932EC021D830
Output28 0x0FD2B2B66AF18DD0 0x779C96BF20FAAC65
Output29 0x779C96BF20FAAC65 0x93C6F9F9FA2026BD
Output30 0xFCB0833058A7183F 0x5397DA646711A886
g = PCG64(31415,(328721727944725361000316204835460899641>>1),variant="dxsm",mode="legacy"); g2 = PCG64(31415,(310562926860152171527627315904638552709>>1),variant="dxsm",mode="legacy");
for i in range(30): print("0x" + format(g.random_raw(), "016X") + " 0x" + format(g2.random_raw(), "016X"))
Multiplier 15750249268501108917 15750249268501108917
Increment 328721727944725361000316204835460899641>>1 310562926860152171527627315904638552709>>1
Seed 31415 31415
Output1 0x0 70E695F12FAC872 0x3 847B59A89C311E2
Output2 0x6 C673BB08B64385F 0xB 565D0C976C04FB6
Output3 0x8 D353EED117D7BC2 0xF C673BB08B64385F
Output4 0x9 EA14B4ED2206371 0x0 06B1E786214329E
Output5 0xB FE0FB0D66377C3C 0xE EA14B4ED2206371
Output6 0x8 F48FEB9E21CF90C 0xB C9512DDD19B53D4
Output7 0x9 FE6F7ED18A90B3E 0xC F48FEB9E21CF90C
Output8 0x8 554B31E0632BF9F 0x2 82E54E6060CFF52
Output9 0xB D2444268D86C2E0 0xF 554B31E0632BF9F
Output10 0x6 A77908E23FC25DB 0xE BE330DEB6411006
Output11 0x7 F5401944A241692 0xB A77908E23FC25DB
Output12 0x3 78E7CFCA99985EC 0x6 1E2C802A1208A6E
Output13 0xE B3C49C3FC1B80BD 0xF 78E7CFCA99985EC
Output14 0x0 CE124E21F2F325C 0xA F5923BC63DFE91F
Output15 0xF 2DAAFA5A3C0D13C 0x4 CE124E21F2F325C
Output16 0x1 4B999F605D4C93B 0xD 00E469E490FE6A4
Output17 0x3 4CAE614E3FBF077 0xC 4B999F605D4C93B
Output18 0x3 BA4BA78F570240F 0xE 5AFD46A52CC2195
Output19 0xD 935DBA5BB7508AA 0x6 84B89E8D66E1609
Output20 0xE B3D1F1A9262C709 0x7 8C2397180142176
Output21 0xB 7AEF7982643BADC 0xB B3D1F1A9262C709
Output22 0x1 C258C8417669CD1 0x2 542033E81E98834
Output23 0x4 81A95DC0F79E1A6 0xC C258C8417669CD1
Output24 0x1 227C217600F6ECC 0xF 3E4B6B862CC276A
Output25 0x6 F0860C9B8E5E021 0xD 227C217600F6ECC
Output26 0xC 72BDAFE8A09D355 0x5 3D268E5FE4D6083
Output27 0x2 69759DA86213109 0x7 72BDAFE8A09D355
Output28 0x8 46C4CD6EC69A47D 0xB D9032549CBE8217
Output29 0xE 3FC3F0A98C99CF1 0x1 46C4CD6EC69A47D
Output30 0xC 7C7EC7A33D0292F 0x3 4D9727EA1FBECFB

An example of the upper part of the LCG in PCG64-DXSM being modified with identical seed in numpy/randomgen

g = PCG64(31415,(292528383318202715988945170563770901305>>1),variant="dxsm",mode="legacy"); g2 = PCG64(31415,(140421743439297021051919259480919575173>>1),variant="dxsm",mode="legacy");
for i in range(30): print("0x" + format(g.random_raw(), "016X") + " 0x" + format(g2.random_raw(), "016X"))
Multiplier 15750249268501108917 15750249268501108917
Increment 292528383318202715988945170563770901305>>1 140421743439297021051919259480919575173>>1
Seed 31415 31415
Output1 0x97F9738805252 FBF 0x3A48F167D2DF3 6B7
Output2 0x964B11CABAA4E 501 0x88DECF43C2B52 E8D
Output3 0xB6AC157505409 594 0x73D73CEDB2296 501
Output4 0xCEC2A042E362F 2A4 0xE36B6340C1CDC FC3
Output5 0xD0A2096F73ED9 41A 0x28A909ED3D7C7 2A4
Output6 0x7127C22885CC5 4A3 0x2F3751079E58B CB4
Output7 0x90A13F2459C9B 6CE 0x5EB33E911942C F94
Output8 0x496FE1695C009 C55 0xE05801B1AA7F2 AF6
Output9 0x80126568D4AA5 FDF 0x8204715BB013E 169
Output10 0x85BC9BD98E5DE FA4 0x53456ECD3C705 21D
Output11 0xA7380BD92D338 178 0x901391E7BC83E 69A
Output12 0x3E324902274F1 0C2 0xC1698DE771445 A88
Output13 0xA5584406CB702 00A 0x54EC4E180FAC9 0C2
Output14 0x736CBD359BEE5 8B5 0xF43324BCA3F47 26E
Output15 0x7F72C7D6A6C6B 778 0x48C873AED7047 0E2
Output16 0x7CAD149EE868F 197 0x6F3A19369FE36 048
Output17 0x30B0B3F452E1F 475 0x31B0038A96D97 197
Output18 0x36514492F155F FD8 0x2586DFDD55D21 2EF
Output19 0x0CE19FA5F24DA C42 0x88058C6DBD897 FD8
Output20 0xE5C9DECAE4A12 C0D 0x5040EC24F3386 95E
Output21 0xE43F8183F92C1 450 0x064D651C1466D 7C3
Output22 0x4E84BB152C42A D6C 0x36D952B70BFA0 870
Output23 0xA4CD58BA22302 BB5 0x3C74E5804A742 D6C
Output24 0x360F2AB984C9C 065 0x33E5305BEC81D 936
Output25 0x50B420A99712E 267 0x0E3141A4260BF B79
Output26 0xD5F0C6071AE99 AEB 0xA9AEDA617F487 C03
Output27 0x8354DDF7179B0 638 0x4027BB1478F1E C11
Output28 0xCE21CF50C0F0E D3F 0xAA188AB00050F 05E
Output29 0xD08A6974E1276 809 0x21370D1D12353 313
Output30 0x2D33EC6185398 A0C 0x5F439A9086378 B2C
Filed under: Cryptanalysis,Pseudo random number generators — Michael @ 18:08


  1. Amazing. Noticed that in the first example, the relationship between three increments is

    31500498537125674621 = 15750249268624565705 + (15750249268501108917 – 1) = 123456789 + 2 * (15750249268501108917 – 1).

    And in the second example,

    1134925067785824341058664978895077376 = (15750249268501108916 – 1) * 72057594037927936

    So to “correctly” peak params for different PCG-DXSM streams, is it enough to just avoid using increments that are coresidual to (MULTIPLIER-1)?

    Comment by thynson — 2024-03-01 @ 09:23

  2. Ive updated the article with additional cases which do not have (MULTIPLIER-1) as coresidual in Z
    Thanks for your comment

    Comment by Michael — 2024-03-02 @ 15:23

  3. After some reading, I would like to say that, when different stream was wanted they should be initialized with same seed. Just like that it’s suggested to create “streams” in other PRNG via jumpahead with a huge step, instead of reseeding with abitrary number.

    Comment by thynson — 2024-03-04 @ 10:30

  4. Correlations also occur with identical seeds.

    Comment by Michael — 2024-03-04 @ 23:07

  5. I’m not mean to say using same seed for different streams avoids correlations, but it’s how it designed to to be used.
    I created an Github issue there:

    Comment by thynson — 2024-03-05 @ 02:38

RSS feed for comments on this post.

Leave a comment

Powered by WordPress