Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Go1.22からの疑似乱数生成器について/go-122-pseudo-random-gener...
Search
convto
March 18, 2024
Programming
2
690
Go1.22からの疑似乱数生成器について/go-122-pseudo-random-generator
2024/03/18(月) Go 1.22 リリースパーティ にて発表した内容です
https://gocon.connpass.com/event/310606/
convto
March 18, 2024
Tweet
Share
More Decks by convto
See All by convto
gob バイナリが Go バージョンによって 出力が変わることについて調べてみた / Investigating How gob Binary Output Changes Across Go Versions
convto
0
94
Go 関連の個人的おもしろCVE 5選 / my favorite go cve
convto
3
390
バイナリを眺めてわかる gob encoding の仕様と性質、適切な使い方 / understanding gob encoding
convto
6
2.5k
みんなでたのしむ math/big / i love math big
convto
0
240
Go1.20からサポートされるtree構造のerrの紹介と、treeを考慮した複数マッチができるライブラリを作った話/introduction of tree structure err added since go 1_20
convto
0
1k
byte列のbit表現を得るencodingライブラリ作った
convto
1
1.2k
Go runtimeの歩き方/how to follow go runtime function
convto
1
970
入出金ドメインの苦労話と解決へのアプローチ/funds in/out difficulties and solutions
convto
2
1.3k
rsa_understanding_memo
convto
0
600
Other Decks in Programming
See All in Programming
Denoでフロントエンド開発 2025年春版 / Frontend Development with Deno (Spring 2025)
petamoriken
1
1.3k
List とは何か? / PHPerKaigi 2025
meihei3
0
550
アプリを起動せずにアプリを開発して品質と生産性を上げる
ishkawa
0
220
PHPによる"非"構造化プログラミング入門 -本当に熱いスパゲティコードを求めて- #phperkaigi
o0h
PRO
0
1.1k
今から始めるCursor / Windsurf / Cline
kengo_hayano
0
110
PHPUnit 高速化テクニック / PHPUnit Speedup Techniques
pinkumohikan
1
1.2k
PHPでお金を扱う時、終わりのない 謎の1円調査の旅にでなくて済む方法
nakka
3
1k
JavaOne 2025: Advancing Java Profiling
jbachorik
1
310
なぜselectはselectではないのか
taiyow
2
310
プログラミング教育のコスパの話
superkinoko
0
120
Fluent UI Blazor 5 (alpha)の紹介
tomokusaba
0
140
AIエージェントを活用したアプリ開発手法の模索
kumamotone
1
740
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
45
9.5k
How STYLIGHT went responsive
nonsquared
99
5.4k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Designing Experiences People Love
moore
141
23k
4 Signs Your Business is Dying
shpigford
183
22k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.8k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Mobile First: as difficult as doing things right
swwweet
223
9.5k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
102
18k
Writing Fast Ruby
sferik
628
61k
Transcript
Go 1.22 からの疑似乱数生成器について 2024/03/18(月) Go 1.22 リリースパーティ
自己紹介 @convto 株式会社LayerX所属 レイヤ低めの技術などに興味がありま す (読みはこんぶとです)
contents - リリースノートななめ読み - ChaCha8 概要 - ChaCha8 が runtime
に実装された - ChaCha8 が math/rand 規定アルゴリズ ムに - PCG-DXSM が実装された - おまけ: 規定アルゴリズムが ChaCha8 に決まった議論おさらい - まとめ: これからの math/rand の使い方
リリースノートななめ読み
math/rand/v2 がでて、変更てんこ盛り https://tip.golang.org/doc/go1.22#math_rand_v2
math/rand/v2 がでて、変更てんこ盛り https://tip.golang.org/doc/go1.22#math_rand_v2 今日お話するのはこのへんです
新しい疑似乱数生成器が入った - ChaCha8 と PCG というやつが入った - ChaCha8 は暗号学的な強度を持っていて、PCGと実行コストが同程度 -
ChaCha8 が math/rand/v2 トップレベルや runtime, math/rand の seed なしの トップレベルで採用
新しい疑似乱数生成器が入った - ChaCha8 と PCG というやつが入った - ChaCha8 は暗号学的な強度を持っていて、PCGと実行コストが同程度 -
ChaCha8 が math/rand/v2 トップレベルや runtime, math/rand の seed なしの トップレベルで採用
新しい疑似乱数生成器が入った - ChaCha8 と PCG というやつが入った - ChaCha8 は暗号学的な強度を持っていて、PCGと実行コストが同程度 -
ChaCha8 が math/rand/v2 トップレベルや runtime, math/rand の seed なしの トップレベルで採用 ChaCha8, PCG について概要などを触 れつつ、どのように導入されたか整理し ていきます
ChaCha8 概要
ChaCha8 って? - ストリーム暗号の一種 - 暗号学的な強度があるとされている - 実行コストが軽く、ハードウェアサポートがなくても結構はやい - めちゃめちゃ簡素な説明をすると、入力や定数から内部状態をつくり、それをラウン
ド関数でかき回して疑似乱数を作り、XORとることで暗号化/復号をする - 内部でかき回すラウンド関数の数によって ChaCha N みたいな表現をする - 詳細に立ち入りすぎると時間が足りなくなるので触りだけ紹介
ChaCha 概要 - 入力や定数からなる 4byte * 16 の内 部状態を持つ -
これをめっちゃかき回す - 4byte * 4 の単位でかき回す関数 Quarter Round が定義されてるの で、それをぶん回しまくる - 内部カウンタがあるので、カウントアッ プしながら疑似乱数列 stream を吐く
ChaCha しくみ概要 - 入力や定数からなる 4byte * 16 の内 部状態を持つ -
これをめっちゃかき回す - 4byte * 4 の単位でかき回す関数 Quarter Round が定義されてるの で、それをぶん回しまくる - 内部カウンタがあるので、カウントアッ プしながら疑似乱数列 stream を吐く Go 1.22 ではこの部分を 疑似乱数生成器として採用
ChaCha かき回し方 - Quarter Round という関数を内部状 態にかけて回る - column 方向に4回(1ラウンド)、
diagonal 方向に4回(1ラウンド)、計2 ラウンドで1セット - ChaCha8 はこれらを4回繰り返す(計 8ラウンド) colmun diagonal
ChaCha Quarter Round 関数 - Quarter Round という名前の関数が 定義されてる -
ようは 4byte * 4 の入力を受け取っ て、bit演算とかシフトを使って値をめ ちゃめちゃかき回す処理 - 良さげな図を見つけたのでペタリ https://en.wikipedia.org/wiki/Salsa20#ChaCha _variant
ChaCha8 が runtime に実装された
internal/chacha8rand 実装 - ChaCha8 自体の実装は internal/chacha8rand にある - 各アーキテクチャ向けに最適化し てる部分もあるが、先ほど話した基
本的な操作をしていることは確認で きる - 参考程度に操作がわかりやすい実 装を貼った。column round & diagonal round をこなして状態を 混ぜてるのがわかる https://cs.opensource.google/go/go/+/refs/tags/go1.22 .1:src/internal/chacha8rand/chacha8_generic.go;l=17 4-185
runtime 実装 - runtime rand としてよしなに使わ れている - スレッドごとに `chacha8.State`
が 初期化されてるので、そこから値を 読み出している - 排他制御もしてる https://cs.opensource.google/go/go/+/refs/tags/go1.22 .1:src/runtime/rand.go;l=125-147
ChaCha8 が math/rand 規定アルゴリズムに
math/rand/v2 - linkname ディレクティブでさっき紹 介した runtime.rand が使われてる - math/rand/v2 では
Source interface に破壊的変更が入ってい て `Uint64()` だけでよくなってる - runtime.rand は排他制御してるの で気にせず使ってOK https://cs.opensource.google/go/go/+/refs/tags/go1.22 .1:src/math/rand/v2/rand.go;l=247-263
math/rand/v2 注意 - 普通に NewChaCha8() すると internal 実装が使われるんです が、Uint64() とかを見たけど排他
制御とか特にしてなさそうに見える ので注意。自分でやる必要がある - とくに理由がなければトップレベル のものを使いまわせばよさそう https://cs.opensource.google/go/go/+/refs/tags/go1.22 .1:src/math/rand/v2/chacha8.go;l=7-20
math/rand - 基本的には似ていて、 runtime.randを被せている - runtime.rand は Seed() に類する 実装がないのでその考慮が必要
- 詳細は割愛するが `randautoseed=0` とするか `math.Seed()` が呼び出されると runtime ChaCha8 ではない別の randSource に差し替えるような実 装が入っている https://cs.opensource.google/go/go/+/refs/tags/go1.22 .1:src/math/rand/rand.go;l=349-369
PCG-DXSM が実装された
PCG概要 - LCG(線形合同生成器) という疑似乱数生成器と置換関数を組み合わせることで、 統計学的な性質を改善したもの - たとえば、LCGは内部で mod を取るが入力として渡す法が2べきだと下位bitの周 期が短くなる既知の性質があったが、そのあたりも改善している
- 内部状態や置換処理によっていくつかのファミリが定義されている
PCG-DXSM 概要 - PCGファミリの一つ - 2019年生まれなのでかなり若い - `double xorshift multiply`
の略らしい - 厳密な spec 定義が見当たらなかった?ので知ってる方いたら教えてください。今 回はcppの実装とかGoの実装とかを見てきました
PCG 導入 proposal で論文著者の O'Neill 氏もコメントしてい る https://github.com/golang/go/issues/21835#issuecomment-739065688
Go の PCG-DXSM 実装 - 基本的にはLCGを進めたあといろ いろかき回してるよう(LCGも定数 カウンタを使っていたりして多少毛 色が違う感じがある) -
以下の操作をしてる - hi 下位半分でXOR - 定数で mul - hi 上位1/4でXOR - hi と下位1bitをたてた lo で mul https://cs.opensource.google/go/go/+/refs/tags/go1.22 .1:src/math/rand/v2/pcg.go;l=100-121;bpv=0;bpt=0
おまけ: 規定アルゴリズムが ChaCha8 に 決まった議論おさらい
proposal での議論で言及されていた https://github.com/golang/go/issues/61716#issuecomment-1668850572
ChaCha8 にした背景 - もともと使ってた lockedSource は PCG, ChaCha8 と比較して相対的に堅牢性が 低い
- 実装した PCG と ChaCha8 の実行コストはだいたい同じ(とプロポーザルで言及さ れていた) - だったらChaCha8のほうが暗号学的強度が見込まれるのでより望ましいだろう! - (余談だけど、このスレをおうと rsc が「crypto/rand との誤用を避けるために math/rand/v2 で Reader けしたけど、今後も ChaCha8 みたいな暗号学的強度が あるものを top level で採用し続けるならそのうち復活させてもいいかもなぁ」みた いなこともぼやいていて面白い)
まとめ: これからの math/rand の使い方
これからの math/rand ってどう使えばいい? - math/rand/v2 利用を推奨。Source interface が整理されたり、危険な利用をされう る実装が消えたりいろいろ良い変更が入っている -
Read が消えたりとか - top level の処理では ChaCha8 使ってたり排他制御も考慮されている。特別な ユースケースでなければ top level のものを単に利用するだけでよい - math/rand では top level `Seed()` を呼ぶと randSource が切り替わる。理由がな ければ top level `Seed()` は使わないようにしよう
これからの math/rand ってどう使えばいい? - v2 で seed を固定化したいときは top level
じゃなくて自前で `NewChaCha8()` や `NewPCG()` したものを使えばいい! - ↑するときは排他制御を自前で作る必要がある(はず)なので注意
ご清聴ありがとうございました