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
640
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
85
Go 関連の個人的おもしろCVE 5選 / my favorite go cve
convto
3
380
バイナリを眺めてわかる gob encoding の仕様と性質、適切な使い方 / understanding gob encoding
convto
6
2.4k
みんなでたのしむ math/big / i love math big
convto
0
230
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
950
入出金ドメインの苦労話と解決へのアプローチ/funds in/out difficulties and solutions
convto
2
1.3k
rsa_understanding_memo
convto
0
590
Other Decks in Programming
See All in Programming
Java Webフレームワークの現状 / java web framework at burikaigi
kishida
9
2.2k
『GO』アプリ データ基盤のログ収集システムコスト削減
mot_techtalk
0
130
Visual StudioのGitHub Copilotでいろいろやってみる
tomokusaba
1
180
Rubyで始める関数型ドメインモデリング
shogo_tksk
0
130
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.4k
AWS Organizations で実現する、 マルチ AWS アカウントのルートユーザー管理からの脱却
atpons
0
160
データベースのオペレーターであるCloudNativePGがStatefulSetを使わない理由に迫る
nnaka2992
0
210
バックエンドのためのアプリ内課金入門 (サブスク編)
qnighy
8
1.8k
Conform を推す - Advocating for Conform
mizoguchicoji
3
700
Code smarter, not harder - How AI Coding Tools Boost Your Productivity | Angular Meetup Berlin
danielsogl
0
100
Domain-Driven Transformation
hschwentner
2
1.9k
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
521
39k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
6
560
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
Become a Pro
speakerdeck
PRO
26
5.1k
The Invisible Side of Design
smashingmag
299
50k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Building Adaptive Systems
keathley
40
2.4k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
How to Ace a Technical Interview
jacobian
276
23k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
7k
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()` したものを使えばいい! - ↑するときは排他制御を自前で作る必要がある(はず)なので注意
ご清聴ありがとうございました