新聞を読んでいたら, おお, 以前同じ会社で働いていた人の会社やないか. すごいなあ. ちなみにサイボウズも少し前から副業OKになってる.
新聞を読んでいたら, おお, 以前同じ会社で働いていた人の会社やないか. すごいなあ. ちなみにサイボウズも少し前から副業OKになってる.
UTF-16用strstrなど
SSE4.2の文字列処理命令を使ったCライクな文字検索ライブラリ(string.hpp). ちまちまとUTF-16対応を進めてる. 恐らくwcslenなどはVCのライブラリを使えばよいが, std::stringライクなNULLターミネートされない範囲指定バージョンは無いので自分で作ってる. パラメータがbyte長ではなく文字の長さなのでときどきはまってるが大体できてきた. テストが酷いことになってるのできれいに書き直して漏れが無いようにしたい.
大学のときの知り合いと会う
前回は3年半年前だった. そんなに経ってたっけ. 東京でちょっと打ち合わせをしたいときに利用できるラウンジが品川にあるらしい. へぇ.
楕円曲線上の鍵共有サンプルコード
以前からちまちまと作ってるライブラリgithub.com/herumi/mieを使うと ecdh_smpl.cppのようにかける.
先日公開されたゲノム情報研究センターの楕円エルガマル暗号のライブラリでも使われている.
会社の食事会
本社の合同食事会に参加させてもらった. こういうのは初めてだ. ありがたい. 恵比寿のロブションという普段なら見もしない高級そうなお店. ここはお城か? お肉がおいしかった.
『下妻物語』(嶽本野ばら)
昔読んだし, 映画も見たけどまた読んでみた. やっぱり面白い. 借りたものは返さない, 友達はつくらないという桃子は凄い.
『脊梁山脈』(乙川優三郎)
23歳で終戦を迎えた主人公が戦後どうやって生きるのかを模索する. 復員列車の出だしや木地師に興味を持ってそれを調べるところなどはとてもよかった. 文章がすばらしい. ただ周りの女性の強さに対して主人公のヘタレっぷりが読んでていらいらする.
std::random_deviceとrdrand
rdrandはIvy bridge以降のCPUに搭載された乱数発生命令. シミュレーション用ではなく, 暗号論的に安全な乱数が必要な時に使うものとして用意された. これがどれぐらいの速度なのか計ってみた(rdrand.cpp).
XorShiftとstd::mt19937と比較してみる. まずはSandy Bridgeで
XorShift | mt19937 | random_device | |
---|---|---|---|
Linux gcc-4.8.2 | 9.60 | 13.09 | 874 |
Win7 VC2013 | 5.67 | 9.84 | 2309 |
XorShiftはさすがに速い. MTもよい. SFMTならもっと速そうだ. もちろん, 暗号論的擬似乱数が必要なときにXorShiftやMTは使えないので念のため.
random_deviceはかなり遅い. Windows版は特に遅い. この遅さの理由と改善方法は後で触れる. 次にHaswellで
XorShift | mt19937 | random_device | rdrand | |
---|---|---|---|---|
Linux gcc-4.8.1 | 7.87 | 9.78 | 310 | 291 |
rdrandはintrinsic関数を使えば
uint32_t use_rdrand() { for (int i = 0; i < 10; i++) { uint32_t x; if (_rdrand32_step(&x)) return x; } fprintf(stderr, "_rdrand32_step err\n"); exit(1); }
こんな感じでお気軽に使える. _rdrand32_step(rdrandのintrinsic関数)は乱数を生成するためのエントロピーが足りなかったときエラーを返す. たまるまでしばらく待つ. ちょっと試した限りではrdrandの数百万回連続呼び出し程度では_rdrand32_stepがエラーを返すことはなかった.
さて, Haswellのrandom_deviceはSandy Bridgeの2倍以上速い. これはなぜだろう. コードを追いかけるとgccのrandom_deviceはrdrandが使えるときそれを使っていた. つまり殆ど上記コードと変わらないものだった.
これはIntelがrdrandにバックドアを仕掛けていたときのことを考える人にはいやなことかもしれない. 一応random_deviceに"/dev/urandom"というトークンを渡すと通常の/dev/urandomを使うモードに切り換えることができる.
uint32_t use_random_device() { static std::random_device rd("/dev/urandom"); return rd(); }
心配性な人はそちらをつかえばよいだろう. なおそのときの速度は860clk程度でSandy Bridgeとほぼ同じだった.
なお, 自分で"/dev/urandom"をopenしてreadしたい場合, システムコールのopen, readを使うよりはCライブラリのfopen, freadを 使う方がずっと速いことに注意. これは後者が大きめのバッファをとってそれを切り崩すからである.
ちなみにWindows版のrandom_deviceは内部でrand_sというライブラリ関数を呼んでいる. そしてこの関数の実装ではCryptGenRandom等が使われている. Windows上のrandom_deviceがgccに比べてずっと遅いのはこの関数の初期化処理などが重たいためなようだ. 実際, それらのAPIを自分で呼び出し, 大きめにバッファをとって切り崩すことをしてみた(random_generator.hpp).
すると, Sandy Bridgeでrandom_deviceと同等と思われる(多分:もしかしたらパラメータが違うのかもしれない)処理が71clkと30倍以上速くなった. これはLinuxの/dev/urandomより10倍ぐらい速い.
OpenSSL Heartbleed
影響が大きいらしい. ssl/d1_both.cの変更点を見てみる(一部).
バグあり版.
unsigned int padding = 16; /* Use minimum padding */ /* Read type and payload length first */ hbtype = *p++; n2s(p, payload); pl = p; if (s->msg_callback) s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg); if (hbtype == TLS1_HB_REQUEST) { unsigned char *buffer, *bp; int r; /* Allocate memory for the response, size is 1 bytes * message type, plus 2 bytes payload length, plus * payload, plus padding */ buffer = OPENSSL_malloc(1 + 2 + payload + padding);
修正版.
unsigned int padding = 16; /* Use minimum padding */ if (s->msg_callback) s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, &s->s3->rrec.data[0], s->s3->rrec.length, s, s->msg_callback_arg); /* Read type and payload length first */ if (1 + 2 + 16 > s->s3->rrec.length) return 0; /* silently discard */ hbtype = *p++; n2s(p, payload); if (1 + 2 + payload + 16 > s->s3->rrec.length) return 0; /* silently discard per RFC 6520 sec. 4 */ pl = p; if (hbtype == TLS1_HB_REQUEST) ...
n2s()は2byteデータを読むマクロ. 関数の最初でpayloadを読んでいた部分がrrec.lengthのサイズを確認してから読むように変更された.
そりゃそうだろうなあ. ところで1とか2とかのマジックナンバーを直接書いてると名前をつけた方がいいと思ってしまう. というかせっかくunsigned int padding = 16;って定義してるのに + 16 なのは焦ってたのかな. まあ, こういうのは他人が見るといくらでもいちゃもんはつけられてしまうものなので止めとこう.
バグ
この半年ぐらいいっしょに作業してたプロジェクトの中間発表に参加しててメインの人がデモを始めたらサーバが固まって苦笑するしかなかった. 何日か前から何度か, 当日の始まる前にも動くことを確認してたのになあ.
後で調べたら, 作ってたもの自体が悪いのではなく, 発表時の操作ミスでそれが呼び出してる別のモジュールの潜在的なバグを出してしまったせいだった.
まあ, それも含めたトータルな試験はこれからやっていく予定なのでそういうのをどんどんつぶしていかないと.
『ペンギン・ハイウェイ』(森見登美彦)
ちょっと小生意気だけど真剣に研究してる小学4年生が主人公. 秘密基地や探検のあたりでなぜか『誰も知らない小さな国』(佐藤さとる)を思い出す. あちらの現代版みたいな感じ(と思ってしまった).
話自体は単調なんだけど, 個別のエピソードやフレーズで気に入ったものが多い. プールで主人公がいじめられたときの対応もよいが, それに対するお母さんのコメントも凄い. お父さんにノートのつけ方や問題解決の方法を教わってるシーンもとてもすばらしいと思う.