Recently in C/C++ Category

ippsRSAEncrypt/ippsRSADecryp 関連のネタ、その2。

IPP 7.0 で警告が出るとは言え、とりあえず動くようになった ippsRSAEncrypt なのですが、なぜか IPP 6.1 で作ると、暗号化されたデータがすべて 0x00 になるという謎が…

う~ん… ippsSetOctString_BNU で変換して ippsSet_BN しているのがまずいのかなぁippsSetOctString_BN を使って値をセットしても、その後の演算でオーバーフローを起こしてしまうんだよね。

IPP 7.0 で動作してIPP  6.1 で動かないというのは謎だなぁ。

しばらく忙しくて何も書けなかった…やっと落ち着いてきたので、いろいろ調べたことを書いてみます。

何となく作って見ようと思って ippsRSAEncrypt/ippsRSADecrypt を使ったコードを書いてみました。深い意味は無くて、何となく作って見たのですが…結構はまった。というか、日本語の資料がほとんどない!

まず RSA を使う場合、巨大な数を扱えるようにする必要があります。IPP の場合、Big Number Arithmetic という項目にある関数群ですね。

基本的には ippsSet_BN を使えばいいだけなのですが…これが、まずはまる原因でした。

ippsSet_BN はマニュアルを見ればわかるのですが、与えられる数が 32bit(Ipp32u) の配列です。で、最初はもらった数値をキャストして渡せばいいんだろう。と思っていたら…全然違った。

どうもエンディアンの問題で(Intel の中の人曰く)うまく動かないらしい。なので、ippsSetOctString_BNU を使って Ipp8u から Ipp32u に変換して、ippsSet_BN すれば OK。

また、IppsSet_BN を行う場合、第一引数に IppsBigNumNEG を指定しないと動きません。

でも、ippsSetOctString_BNU って、IPP 7.x からは「次のバージョンで使えなくなるよ?」みたいな警告が出るんだよね(^^ゞ

WTL

| No Comments | No TrackBacks

なんとなく思い立ってWindows Template Libraryで遊んでみました。

最終リリースが去年の5月だからでしょうが、VisualStudio 2010 でコンパイル出来ないのが多かったので、その対策のメモ。

  • ビルド時「プロジェクトはこのソリューション構成に対してビルドするように選択されていません。」と出ることがある。
    構成ファイルのビルドにチェックが入っていないのが原因。てか、なんで入らないんだろう?
    • ソリューションエクスプローラータブのソリューション'ほげ'のプロパティを開く
    • 構成プロパティの一番右にある Build をチェック
  • ビルド時「CVTRES : fatal error CVT1100: 重複するリソースです。」などと出て、リンクエラーになる。
    COFF への変換中に障害が発生しました~とか言われてちょっとびくっとしたり。
    • プロジェクトのプロパティ
    • マニフェストツール
    • 入出力
    • 埋め込みマニフェストを「いいえ」にする
  • stdafx.cpp をコンパイル中に include ファイルを開けません。'atlapp.h' と言われる。
    • プロジェクトのプロパティ
    • C/C++の全般タブの「追加のインクルードディレクトリ」に ..\..\include を追加
  • 「fatal error RC1015: cannot open include file 'atlres.h'.」と言われる
    リソースファイル(.rc)から include しているファイルがある
    • プロジェクトのプロパティ
    • リソースの全般タブの「追加のインクルードディレクトリ」に ..\..\include を追加

しかし、WTL はもう古いのかな?まぁ今だと wxWidgets や QT があるからなぁ(^^ゞ

Windows2000 と rand_s のお話

| No Comments | No TrackBacks

最近の VisualStudio には rand_s という便利な関数があります。主に乱数の初期値として使える関数で、よくある GetTickTime を使った時なんかよりかなり優秀な乱数の種を与えてくれます。

で、MSDN のページや黒翼猫さんのページに書いてあるようにこの関数、Windows 2000 では動きません。

というか、動かないどころか EXE を実行すると「有効な Win32 アプリケーションではありません」とか言われてしまうのです。

で、不思議なのがこの関数、MSDN のページにも書いてあるのですが内部でRtlGenRandomという関数を呼び出します。ところが、この関数の説明を読んでみると、最初に

[The RtlGenRandom function is available for use in the operating systems specified in the Requirements section. It may be altered or unavailable in subsequent versions. Instead, use the CryptGenRandom function.]

とっても意訳

「RtlGenRandom 関数は OS によって使えなかったりするよ。代わりに CryptGenRandom 関数を使ってね!」

……ちょ、おまwwww自分で言っているんだから CryptGenRandom 関数を使えよ。てか、そのおかげで原因がわからず偉い苦労したんだぞwwww

と、ひとしきり頭を痛めた日でした。

な~んで RtlGenRandom で実装しているんだろうなぁ。VisualStudio2010 でも同じだし。

VisualStudio2010 と Windows2000

| No Comments | No TrackBacks

VisualStudio2010 が出たので、開発用のコンパイラも入れ替えたのですよ。で、うきうきしながらコーディングしていたのですが、思わぬ落とし穴が。

VisualStudio2010 で作られた実行ファイルが Windows2000 で動作しない!

いや、もう、ね。DLL が足りないとか、エントリーポイントが足りないとか、関数がないとか、そういうレベルではなくて、Windows2000 で実行すると「有効な Win32 アプリケーションではありません」と言われてしまうのですよ。

もうおまえは何を言っているのかと(以下略)

これは正直困りました。いろいろと検索してみたら、ランタイムライブラリをリンクしない というページがあったりして、ん~strcpy(_s)じゃなくて、lstrcpyを使えばいいのかな~とか、そもそもstd::string使えよ!?ってことかな~とかいろいろと考えたのですが、結局 VisualStudio2008 もインストールして両方で作ることにしました。

それと、上記ページにあった subsystem バージョンを変更する方法は 5.0 に設定すれば DecodePointer がないよ。と言われたので、DecodePointer を乗っ取ればいけそうなのですが、そもそもこの関数が何をするのかわからなかったのでやめました。

そのうち時間を見つけて WindowsDriverKit の方を調べてみるかな。

windows で hash 計算 その2

| No Comments | No TrackBacks

あんまし難しく考える必要なかった(´・ω・`)

  • CryptAcquireContext の CSP とか Provider は暗号化の時必要なみたい。だから hash 計算の時は NULL で大丈夫。
  • 第4引数の ProvType は MD5/SHA なら PROV_RSA_FULL で OK。SHA256 とかになると PROV_RSA_AES じゃないと駄目。
  • PROV_RSA_AES は Windows2000 では動かない(と思う)。
  • 第5引数は CRYPT_VERIFYCONTEXT にする。

こんな感じででけた。 でも CryptGetHashParam の第2引数に HP_HASHSIZE を使うと、 PROV_RSA_AES の時に 4 とか帰ってくる。謎だ。

ハッシュサイズの取得は HP_HASHVAL にして、第3引数に NULL を指定すればいいんだけど、なんだか納得いかない(^^ゞ

windows で hash 計算

| No Comments | No TrackBacks

なんとなく思い立って Python の hashlib クラス見たいのを作ってみようと思い立って作成中。

最初は CryptAcquireContext 使えば簡単にできるかな~と思っていたけど… Container(CSP) と Provider にどれを使えばいいのか全くわからん(´・ω・`)

まぁ、英語ドキュメントをがんばって読めば書いてあるんだろうけど…Document Explorer のフォントサイズが小さすぎて読む気が起きないw

設定でフォントサイズを変更すると、InternetExplorer のフォントサイズにも反映されちゃうしなぁ。

しかしこの辺の情報を検索してみてもあんまり出てこないですね。MD5 のみとかなら出てくるんだけど…まぁ、のんびり作りますか

正規表現

| No Comments | No TrackBacks

いろんな言語をいじっていると正規表現の実装の違いで頭を痛めたりすることもあるのですが、C++0x での正規表現のお話し。

なぜC++0xの正規表現は、ECMAScript準拠なのか

これを読んでへぇーと思ってしまった。ちゃんとした規格って二つしかなかったのか。今まで Perl 互換なんて書いてあるオプションを見たりしたけど、そういう理由だったんだね。

wxWidgets メモ

| No Comments | No TrackBacks

wxDialog を継承して作ったウィンドウ(ダイアログ)には EVT_PAINT が飛んでこない。モーダルウィンドウが欲しくて wxDialog を継承して作ったんだけど、微妙に困ってしまった(^^ゞ

まぁ、SDK の CreateDialog で作ったときも WM_PAINT は飛んでこないので、Windows の仕様なんだとは思うけど、SDK の場合は Subclass 化してやれば回避(?)は出来るんだけどなぁ。

wxWidgets で Subclass 化ってどうやるんだろう?

結局 EVT_PAINT を利用しないで描画するようにしたけど、どうやるのが正しいんだろうなぁ。

wxWidgets は楽しいです。今、仕事で作るツールはほとんどこのフレームワークを使って作っています。

その中で wxDirPickerCtrl というクラスがあるのですが、ディレクトリ入力用のテキストボックスと参照ボタンがセットになっているのでものすごく便利です。

ところが普通に配置すると、参照ボタンのラベル名が Browse になってしまってちょっと悲しい。ドキュメントを見た感じだと変更方法は乗っておらず、検索してみたら海外のサイトで「'Browse'をハードコーディングしているのはまずくね?」というようなやりとりがあるだけでした。(もっと探せばあったかもしれないけど、途中であきらめました)

パッチでも当てようかな~と思ってソースを眺めていたら…ボタンコントロールのクラスを取得して変更しちゃえばいいんじゃね?ということに気づいて、やってみたら変更できましたよ。

wxDirPickerCtrl *p = new wxDirPickerCtrl(
  親のコントロール,
  wxID_ANY,
  ディフォルトパス,
  説明 );
p->GetPickerCtrl()->SetLabel( wxT("参照") );

こんな感じで。ちなみに、wxFilePickerCtrl() も同じように出来ます。

GetPickerCtrl() はドキュメントに載っていないメソッドなので、そのうちなくなるかもしれないけど、2.8.9 では残っていました。

でも、wxWidgets はあまり流行ってくれないなぁ。MFC より楽しいのにw

日本語ドキュメントが少ないのも原因なのかな?