補題:32bit符号なし整数変数間の算術和演算をブール関数で表す
初期seedから日時を求める無謀な挑戦 - Plus Le Toolのための補題。
使う記号の定義は[id:plusletool:20130427:p2]参照。
補題:32bit符号なし整数変数間の演算をブール関数で表す - Plus Le Toolの続きみたいなもの。
今回の内容はうまく説明できないものが多いから、証明や計算過程はほとんど省略しちゃった(・ω<)テヘペロ
少し考えれば分かると思うので各自考えてね(投げやり
補題:32bit符号なし整数変数間の演算をブール関数で表す - Plus Le Toolより抜粋。
[id:plusletool:20130505:p1](*30)再掲
(*30)をbit単位で計算する場合、(*31)のように書ける。ただし は繰り上がり項で、(*32)のように漸化式で表される。
(証明はしないけど「全加算器」あたりで検索すればたくさん出るはず。)[id:plusletool:20130505:p1](*31)再掲
[id:plusletool:20130505:p1](*32)再掲
><
2変数の算術和をbit単位の式で表すと上のようになるのだった。
これを関数 を使って書きなおすと次のようになる( については補題:新しい関数“Cr(Ω)”を定義する - Plus Le Tool参照)。
(*1)
※
では、3変数以上の算術和の場合はどうなるのだろう?
とりあえず3変数の場合から見てみよう。
次のような、3つの32bit符号なし変数(uint型)変数 の算術和 を考える。
(※3変数の算術和の結果は最大34bitになるが、上2bit(第33・34bit)はオーバーフローにより無視されるので、実質的には法 のもとでの算術和であると考える。)
(*2)
これをbit単位の式で表すと、(*3)のように書ける。
ただし は繰り上がり項で、(*4)(*5)のように漸化式で表される。
(*3)
(*4)
(*5)
式(*3)(*4)(*5)は について対称形なので、 が使えそうだ。
その場合、次のように書き直せる。
(*6)
※
次に4変数の場合を見てみる。
次のような、4つの32bit符号なし変数(uint型)変数 の算術和 を考える。
(*7)
これをbit単位の式で表すと、繰り上がり項 を使って(*8)(*9)(*10)のように表せる。
(*8)
(*9)
(*10)
これを を使って表すと、次のように書き直せる。
(*11)
※
続いて5変数の場合を見てみる。
次のような、5つの32bit符号なし変数(uint型)変数 の算術和 を考える。
(*12)
これをbit単位の式で表すと、繰り上がり項 を使って(*13)(*14)(*15)のように表せる。
(*13)
(*14)
(*15)
これを を使って表すと、次のように書き直せる。
(*16)
※
ところで、(*6)(*11)(*16)を見比べてみよう。
(*6)再掲
※
(*11)再掲
※
(*16)再掲
※
なんと、これらは( の違いを除いて)まったく同じ式である。
実を言うと、繰り上がりが2桁以下の場合にはすべて(*16)が使えるのだ(ただし変数の個数によって の要素は変わる)。
言い換えると、5変数以下の算術和は最大2桁までしか繰り上がらないので、(*16)は5変数以下の場合に成り立つ式だということだ。
そしてこれは3〜5変数の場合だけでなく、0〜2変数の場合にも(*16)が成り立っているのだ(0変数の算術和って言うとなんだか変な感じがするが、算術和の零元 のことだと思えばいい)。
【簡易証明】
以下の証明では次式を使って式変形していることに注意。[id:plusletool:20130612:p1](*D)再掲
のとき、次の式が成り立つ。[id:plusletool:20130612:p1](*A)再掲( の定義)
(前略)
※ または の場合は、 とする。
※ の場合は、 とする。
<2変数>
この場合、(*16)において と考えればいい。
いま、 , とおくと、 より ( のとき)である。
よって、となるが、 より であり、つまり は定数列 であることが分かる。
(これは2桁上の位への繰り上がりがないことを意味しており、直感にも一致する。)
ここで , とおくと、 より ( のとき)である。
よって、
となるが、これは(*1)と等価である。
よって2変数の場合にも(*16)は成り立つ。<1変数>
この場合、(*16)において と考えればいい。
いま、 , とおくと、 より ( のとき)である。
よって、となり、 は定数列 であることが分かる。
ここで , とおくと、 より ( のとき)である。
よって、となるが、 より であり、つまり は定数列 であることが分かる。
(これは繰り上がりが一切ないことを意味しており、直感にも一致する。)
ここで , とおくと、 より ( のとき)である。
よって、となり、確かに1変数の場合にも(*16)は成り立つ。
<0変数>
この場合、(*16)において と考えればいい。
いま、 , とおくと、 より ( のとき)である。
よって、となり、 は定数列 であることが分かる。
ここで , とおくと、 より ( のとき)である。
よって、となり、 は定数列 であることが分かる。
, とおくと、 より ( のとき)である。
よって、となり、確かに0変数の場合にも(*16)は成り立つ。
上の証明で、(*16)が3〜5変数の場合だけでなく0〜2変数の場合にも成り立つのは、上位への繰り上がり項が常に0になるからだと分かった。
すると逆に、こう考えることもできる。
「5変数までなら3桁上への繰り上がりが0になるので考える必要がなかったが、本来は3桁上への繰り上がり項に当たる式が必要であり、(*16)にはその式が不足しているのだ」、と。
そしてその場合、3桁上の位への繰り上がりが計算できるので、6変数以上の算術和をbit単位で表すことができるようになるはずだ。
この考えに基いて(*16)を拡張してみよう。
めんどうなのでいきなり結果を書いてしまうと、これは3桁上への繰り上がり項 を使って次のように表せる。
(*17)
実際に展開して計算してみると、確かに12変数以下の場合に(*17)は成り立っている。
だったら13変数以上の場合はどうなるの? ……と考えていくとキリがないのだが、同じように考えればさらに拡張できるに違いない。
そしてそれがどんな式になるかは、そろそろ予想がついているんじゃないかと思う。
答えを書いてしまうと、27変数以下の場合は次の式が成り立つ。
(*18)
予想は当ってた?
言うまでもないかもしれないが、 は4桁上への繰り上がり項である。
このように、 項上の位への繰り上がり項は で表される。
なぜそうなるかはうまく説明できないので気になる人は各自考えてほしい。
考え方のヒントだけ書いておくと、 の要素(=ブール変数)の中に値が1である要素(ブール変数)がいくつあれば該当桁への繰り上がりが生じるかを考えれば分かると思う。
さて、「28変数以上の場合は?」などと考えていくと本当にキリがないのでこれ以上はやめておくが、代わりに軽く整理しておこう。
2変数の算術和をbit単位の式で表すと、次のようになるのだった。
(*1)再掲
(*1)は2変数の場合だけでなく0〜1変数の場合にも成り立つ。
つまり、(*1)は2変数以下の場合に成り立つ(ただし は変数の個数に応じて適当な集合を選ぶ)。
同様に、5変数以下の場合は(*16)、12変数以下の場合は(*17)、27変数以下の場合は(*18)がそれぞれ成り立つのだった。
(*16)再掲
(*17)再掲
(*18)再掲
(*1)→(*16)→(*17)→(*18)の順に新しい繰り上がり項が1つずつ増えているだけなので、これらの式自体に不自然な点はないだろう。
しかしこれらの式が成り立つ条件の、「2変数以下の場合」「5変数以下の場合」「12変数以下の場合」「27変数以下の場合」の、2,5,12,27という数はどこから出てきたのだろうか?
答えは簡単だ。次のように考えればいい。
下の位からの繰り上がり項が最大 個であるような算術加算を考える。
このとき、 桁上の位への繰り上がりがないためには、 の要素数は 個以下でなければならない。
の要素には元々の変数の他に下の位からの繰り上がりの変数も含むので、それを除いた数が求めたい値(元々の変数の個数の最大値)になる。
今は下の位からの繰り上がり項が 個の場合を考えているので、 には 個の繰り上がり項が含まれている。
よって から を引いた が求めたい値である。
繰り上がり項の数 を に代入すると、確かに2,5,12,27となる。
さて、これで任意個の変数の算術和演算をbit単位で表すことができるようになったので、ここらで本来の目的を思い出しておこうか。
今の最終目的はSHA−1の逆計算で、その過程で算術和演算を使っているので、それをbit単位の式に書き直そうとしているところだった。
では具体的に算術和演算がどのように使われているかというと、補題:SHA−1アルゴリズムを方程式にする - Plus Le Toolによればこんな形の式になっている。
[id:plusletool:20130608:p1](*7)再掲
ごちゃごちゃしてて見づらいから、次のように文字の置き換えをしようか。
(*19)
見ての通り、5変数の算術和計算である。
であれば6変数以上の場合の式をいじる必要はないので、(*16)についてだけ考えればよさそうだ。
……あぁ、ずいぶん寄り道してしまったようだ。
(*16)再掲
※
この式から何とかして を消去したい。
2変数の算術和の場合には を消去できたんだから、5変数の場合でもできるはずだ(最悪、2変数の算術和を4回行えば5変数の算術和になるわけだし)。
(*16)のままでは計算しづらいのでいったん をやめて元の式にもどしてみようか。
(*20)
(*21)
(*22)
ここで , とおけば、(*20)(*21)(*22)は を使って次のようにまとめられる。
(*23)
(実は[id:plusletool:20130612:p1](*D)を使えば(*16)から直接(*23)へ変形できたのだが、まぁこのくらいの手間ならどっちでもいい。)
[id:plusletool:20130612:p1](*D)再掲
のとき、次の式が成り立つ。
(*23)の第2式( の式)の両辺に を論理積すると、
(*24)
(第2項では[id:plusletool:20130612:p1](*C)を使った。)
[id:plusletool:20130612:p1](*C)再掲
, のとき、次の式が成り立つ。
(*23)の第3式( の式)に(*24)を すると、
(*25)
よって、次の式が成り立つ。
(*26)
のとき なので定義より となり、よって(*26)の第3式( の式)は のときも成り立つ。
(※ の係数はすべて なので、 は任意の有限値でいい。めんどうなら と考えてしまってもいい。)
(*27)
(*27)を(*23)の の式に代入する。
(*23)再掲
(*28)
これでようやく が消去できた。
さて、この漸化式はここから先どうやって解けばいいんだろう。
それは……しばらくほっとけば誰かがコメント欄で教えてくれるんじゃね?残念ながらノーアイディア。
の項がとにかく邪魔で、現状どうにも消去できそうにない。
何かうまい方法がありそうな気はするんだけど……
少なくとも2変数の時は繰り上がり項を消去できたんだから、5変数の場合でもきっと何か方法があるはずなんだ、タブンネ。
とりあえず試行錯誤して失敗した例を書いてお茶を濁すことにする。
【失敗例】
なる について、 を定義する。
(こう置いた理由は、 の第3項 が の第1項 によって相殺されて消えるので、予めこの項(第1項)を消去しておいた方が都合がいいから。)
なお、 より である。(×1)
これを(*28)の漸化式部分に代入して整理すると(×2)のようになる。
(*28)再掲
(×2)
(×2)の1行目を見ると、 , , の対称式になっている。
また、 , の項もその3つのうち2つが係数になっており、もう少しで対称式になりそうだ。
……これはあやしい。
対称式ということは の出番なので、これを使うことにしよう。
そのためにまず、 なる について を定義する。
ただし より , である。(×3)
これを使うと、(×2)は次のように書き直せる。
(×4)
(※途中で (∵ )を使った。)
さらに、 なる について、 を定義する。
ただし より , である。(×5)
これを(×4)に適用すると、次のようになる。
(×6)
……実に惜しい形になった。
第3項( の項)がなければ、あとは比較的簡単に解けたのになぁ。ちなみに第3項の を に置き換えようとするともっと複雑な式になるのであまり意味がない。
一応書いておくと、 より、(×7)
これを(×6)に代入すると(×8)のようになる。
(×6)再掲
(×8)
は消去できたが、どう見ても解けそうな形じゃない。
どうやら を何とかしないと話にならないようだ。
他の方法は今のところ思いつかないので、何か閃いたら追記することにしよう。
【メモ1】
【メモ2】
2変数の場合( )
(日記はここで途切れている。どうやら途中保存のようだ。)