はじめに
素数 mod 上の平方根を求める方法を勉強したので, 軽くまとめます
体とか同型とかそういう言葉を使わないように書いていきたいと思っています
ちゃんと勉強したい人は 37zigenさんのブログ を読んでください
やりたいこと
素数 と 整数 が与えられるので
となるような を一つ求めてください
存在しないならそのことを報告してください
やりかた
めんどくさいのでここから下では をつけません (ごめんなさい)
何も言わずに って書いてあったら だと思ってください
とりあえず
まずは自明なものをはじきましょう
というのも, 今回使う道具は奇素数にしか対応してないです
のとき は か のどっちかですが,
なので, です 簡単ですね
ついでに のときも先にはじきます ですね
ということでここから先は は奇素数, とします
平方剰余
そしたらまずは, そもそも平方根が存在するのかを判定しましょう
まず用語の説明ですが,
「 となる整数 が存在する」とき, 「 は 法 で 平方剰余 である」といいます
オイラーの規準
さて, この判定をすることができる道具として, オイラーの規準 というものがあります
これは,
のとき は 法 で 平方剰余である
のとき は 法 で 平方剰余ではない
というものです これは逆も成り立ちます
がついてますね これのために をはじいたわけです
さて, が でも でもない値になることはないのか? と思うかもしれません (僕は思いました)
これは, ならないことがわかります
フェルマーの小定理より, が素数で が と互いに素であるとき
となります
ということは,
ですね
二乗して になる整数は と しかないので, はそのどちらかになるということです
証明
か になることはわかりましたが, なぜそれで判定できるのでしょう
まず, 「 は 法 で 平方剰余である 」 を示します
は 法 で 平方剰余なので, とある が存在して です
ここで, も と互いに素なはずです (じゃないと になってしまうので)
ということで, フェルマーの小定理より です
は偶数なので と書けますね
ということで です
次に, 「 は 法 で 平方剰余である 」 を示します
ここで, を に対する原始根とします
は原始根なので ある自然数 が存在して と書けるはずです
よって となります
ここで とすると, です
は原始根なので, は の倍数である必要があります
要らない気がしますがこれも証明してみると
が の倍数でない場合,
( は非負整数, ) と書けます
ということは
となるので
です
ここで, なので であるはずですがこれは が原始根であることに矛盾します
ということで は の倍数 です
つまり が偶数であるわけですが, としてみると
と書けるので の平方根 が存在します
証明終わり!
Cipolla's algorithm
ということで解が存在するかどうかの判定はできました
ここからは存在するものとします
ここで, いい感じの整数 を使って
という方程式を作ってみます
の解は, 普通に解の公式を使うと
と書けます
さて, が平方剰余である場合,
ある非負整数 が存在して と書けるので です
だからなんですか?
何もありません
何もないと困るので, は平方剰余じゃないとします
それはそれで困りました 平方剰余じゃないってことは は整数じゃないです
仕方ないのでそのまま残して計算することにします
どういうことかというと, とあったとすると
という感じです
また, 項ごとに mod を取れることにします
ということで計算していきます
書くのがめんどくさいので
とおきます
さて, ここでこいつらの 乗を考えてみます
さっきまでなら フェルマーの小定理から みたいなことが言えましたが, もうそんなものは成り立ちません
を二項定理で頑張ってみましょう
めんどくさいので とおいて
と書けます
について考えてみます
定義より, と書けます
としてみると, 分母の に が登場しません
よって分子の の が約分されないため, は の倍数になります
ということで mod を取ると だけが残って
となります (あれ, 一年生の夢が現実になりました)
ここで, は普通に整数だったのでフェルマーの小定理から です
の方は, が奇数なので と書けます
を に戻すと
となります
は平方剰余ではありませんでしたよね?
ここで, オイラーの規準を思い出してみましょう
は平方剰余ではないので と書けます
これを代入すると
と書けました すっきりしましたね
そんなわけで,
となりました
ここで, 解と係数の関係を考えてみると, です
を代入すると となります
ということで,
です
平方根が見つかりました!!!!
いい感じに終わった風ですが, 問題があります
ちょっと前のところを思い出してみましょう
ここで, いい感じの整数 を使って
という方程式を作ってみます
ってどうやって見つければいいんだ...
さて, この に求められる条件というのは
が平方剰余にならない
ということだけです
実は, が平方剰余であるとして, をランダムに取ってきたときに が平方剰余にならない確率は となります (これの証明はよくわかってません...)
追記: わかりました
が平方剰余になるような がいくつあるかを数えれば, その個数を 個 とすると求めたい確率は となります ( の候補は 個あるので)
さて, 今 は平方剰余であり でないので, とある整数 を用いて と書けます
つまり が平方剰余であるような の個数を数えればいいのですが, なので逆元が存在して, と書けます
とおくと, が平方剰余かどうかを判定すればいいことになります
(オイラーの規準を思い出してあげるとわかりやすいのですが, 平方剰余である数 平方剰余である数 は 平方剰余である数, 平方剰余である数 平方剰余でない数 は 平方剰余でない数 となります)
ここで唐突に という関数を考えてみます の解が存在するためには が平方剰余である必要があります (上の方でやったのとだいたい同じです) これは逆も成立するので同値です
整数 が解の一つ, つまり であるとすると, が残ってしまうので であるといえます よってこいつにも逆元が存在して と書けます
ということで の値が何通りあるのか と変形できました
ここで とすると, なのでこれを因数分解して , つまり と書けます
つまり または です
したがって, なら となり, の個数が と一致します
は 通り存在しますが, それらは を除いて で となるペアが存在します
ということで となります
追記終わり
ということで となりますが,
これはだいたい となります
ということで 回連続で失敗するような確率は だいたい くらいと言えます
何が言いたいかというと, すぐ見つかるということです
まとめ
- や の場合は early return
- を計算して解が存在するか判定
- になるような を頑張って探す
- が答え
計算量は, どのステップも繰り返し二乗法を使って で計算できるので,
で平方根を求めることができました