Try   HackMD

xoroshiro128+の状態遷移の逆算の考察

はじめに

この記事はPokémon Past Generation Advent Calender 2019 一日目の記事です.

なんぞこれ?

  • 某所で話題になっている疑似乱数生成器"xoroshiro128+"の状態遷移の逆関数を求めてみようという趣旨の記事です.

逆関数が求まると何がうれしいの?

  • 初期seedを逆算したりできて色々と便利.
  • 線形代数の計算を実用的な場面で行えるので楽しい(過程が).

xoroshiroの状態遷移の概要

  • xoroshiroは"xor","rotate","shift","rotate"の略らしいです. xorshiftの改良版だとか.
  • xorとビットシフトは乱数調整で遊んでいる人ならよく知っているはずなので省略しますが, rotateはあんまりなじみがないかもしれません. 普通のビットシフトは端からあふれ出たビットは捨てられますが, rotateは逆の端からニュッと出てきます.
  • 1011を左に2bit shiftをかけると1100になりますが, rotateだと1110になります.
  • xoroshito128+は128bitの内部状態を64bit×2で持ち, 64bitの乱数値を返してくれます.
  • 内部状態を64bit整数X,Yで持っているとすると, X+Yで乱数を取得します. MTみたいなtemperingは無い様子.
  • 状態遷移は以下の通りの処理で行われます.
X = rotl(X, 24) ^ (X^Y) ^ ((X^Y) << 16) Y = rotl(X^Y, 37)

方針

  • これと全く一緒. xorとshiftしか使ってない乱数生成器なら全部同じ方針で解けると思います.

実際に計算してみる

(以下常体)

rotl(X,n) =:

Rl(n)M64(F2),
<<16 =:
L16M64(F2)
とおいて,
xn,ynF264
を内部状態X,Yとする.

[xn+1yn+1]=[Rl(24)xn+xn+yn+L16(xn+yn)Rl(37)(xy+yn)]=[(Rl(24)+E+L16)xn+(E+L16)ynRl(37)xy+Rl(37)yn]=[Rl(24)+E+L16E+L16Rl(37)Rl(37)][xnyn].

Rl(n)GL64(F2)で,
Rl(n)1=Rl(64n)
であり,
L16:=E+L16
についても,
F264
においては
b=a+(a<<n)a=b+(a<<n)
であることに注意すると,
x,y
の第
i
bitをそれぞれ
xi,yi
とするとき
xi={yi(1i<n)yi+xin(ni64)

であることから, 可逆であることがわかる. あとは頑張れば逆行列が出る.

簡単のため

Rl(24)=A,L16=B,Rl(37)=Cとおくと,

[xn+1yn+1]=[A+BBCC][xnyn]

と書けてとてもうれしい. これの逆行列を求める.

[A+BBCC][X1X2X3X4]=[E00E]

とすると,

(A+B)X1+BX3=E(A+B)X2+BX4=0CX1+CX3=0CX2+CX4=E

の4本の式が立つ.

A,B,CM64(F2)なので
X=X
であることと, 乗法が非可換であることに注意してこれを解いていく.

下の2本の式より

X3=X1X4=C1+X1.

これを上の2本にそれぞれ代入していく. まず1本目から

(A+B)X1+BX1=EAX1+BX1+BX1=EAX1=EX1=A1.
よって,
X1=X3=A1.

次に2本目から

(A+B)X2+B(C1+X2)=0AX2+BX2+BC1+BX2=0AX2+BC1=0AX2=BC1X2=A1BC1.

よって

X2=A1BC1,X4=A1BC1+C1.

以上から,

[A+BBCC]1=[A1A1BC1A1A1BC1+C1]=[Rl(24)1Rl(24)1L16Rl(37)1Rl(24)1Rl(24)1L16Rl(37)1+Rl(37)1]=[Rl(40)Rl(40)L16Rl(27)Rl(40)Rl(40)L16Rl(27)+Rl(27)].

(

L16の可逆性必要なかった……)

すなわち,

[xnyn]=[Rl(40)Rl(40)L16Rl(27)Rl(40)Rl(40)L16Rl(27)+Rl(27)][xn+1yn+1]

xn=Rl(40)xn+1+Rl(40)(E+L16)Rl(27)yn+1=Rl(40)xn+1+Rl(3)yn+1+Rl(40)L16Rl(27)yn+1yn=Rl(40)xn+1+Rl(40)(E+L16)Rl(27)yn+1+Rl(27)yn+1=Rl(40)xn+1+Rl(3)yn+1+Rl(40)L16Rl(27)yn+1+Rl(27)yn+1.

以上から,

X = rotl(X,40) ^ rotl(Y,3) ^ rotl((rotl(Y,27)<<16),40) Y = rotl(X,40) ^ rotl(Y,3) ^ rotl((rotl(Y,27)<<16),40) ^ rotl(Y,27)

で逆算ができる.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

(https://gist.github.com/yatsuna827/ea985d2ce4d34da1e35ec4adf1862050)

さいごに

明日も私の記事ですね.
まだたくさん空きがあるので参加お待ちしています.