2013/12/09

C/C++で天文学的数字を扱う - LibTomMathの紹介

Java製の暗号化、復号化を行うライブラリをC/C++に移植したことがあるが、その時にJavaのBigIntegerに当たるものがC/C++に無くて困った。
BigIntegerは300桁くらいの数値でも平気で掛け算したり出来るライブラリだ。twitterが普及した時に140字って意外と長いと思ったが、ツイート2つ分くらい、ダーッと数字が並んでるのを想像すると良い。こんな数字は天文学か暗号でしか使わないはずだ…。

さてC/C++には標準でそういったライブラリは含まれていない。で、Boostとかライブラリはいろいろあるんだが有償だったりライセンスが複雑だったり、使い方もそれぞれ全然違うし、何を使えば良いんだ?と困った。 またこういったライブラリでも出来る演算が限られていたりする(忘れたが例えばmod演算の関数が無い、など)ので、必要な関数が全て揃っているか注意すること。

でいくつか探した中でこれが最高と思ったのがLibTomMathというライブラリ。
LibTomというプロジェクトの一つで、Tomさんが作ってるんでしょうか。
他のライブラリは巨大なライブラリ群の中に数値ライブラリが含まれる、というのが多くていかにも重くなりそう(プロジェクトが) だったが、これは数値ライブラリだけの小型のものだった。
また素晴らしいのはライセンスがPublic domainで、それを示す文言もパンクだ。
LibTomMath is public domain.  As should all quality software be.
https://github.com/libtom/libtommath/blob/master/LICENSE
Boostも商用アプリに組み込めるライセンスらしい(どうも文章が固くてだめなのかなと思ってしまった)。C/C++用の任意制度整数ライブラリとしてはLibTomMathはマイナーな方かもしれない。小さくて良いんだけどなぁ。

せっかくなので布教活動として、VisualStudio2010でLibTomMathを使う方法のチュートリアルを作成する。(LibTomMathを使ってDSA署名とそのチェックを行う方法もこちらに

まずLibTomMathのGitHub(https://github.com/libtom/libtommath)より、「Download ZIP」でプロジェクトフォルダをダウンロードしておく。

VS2010でC++プロジェクトを作る(SAMPLEというWin32コンソールアプリを作った)。
出来たフォルダの中にダウンロードした「libtommath」のプロジェクトフォルダ(解凍して出来たフォルダ丸ごと)をコピーする。
 VS2010のソリューションビューのソリューションを右クリック「追加」→「既存のプロジェクト」を選ぶ。
 「libtommath.dsp」を選ぶ(vcprojではない)。追加の過程でVS2010形式に変換される。
SAMPLEプロジェクトのプロパティを編集する。
共通プロパティ、Frameworkと参照の「新しい参照の追加」で「libtommath」を追加する。
構成プロパティ、C++の全般の「追加のインクルードディレクトリ」にlibtommathのディレクトリを追加する。SAMPLEからの相対パスで良いのでこんな感じ。
SAMPLEプロジェクトでlibtommathが使えるようになる。
文字列で現された巨大な数を2つ読込み、掛け算した結果を文字列で表示するサンプル。
#include "stdafx.h"
/*
 * license
 * LibTomMath is public domain. As should all quality software be.
 * Tom St Denis
 */
#include "tommath.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
 mp_int a;
 mp_int b;
 mp_int answer;
 mp_init(&a);
 mp_init(&b);
 mp_init(&answer);
 
 mp_read_radix(&a, "10000000000000000000000000001", 16);
 mp_read_radix(&b, "1234567890ABCDEF", 16);
 
 mp_mul(&a, &b, &answer);
 
 char anschar[1000];
 mp_tohex(&answer, anschar);
 printf(anschar);
 return 0;
}
mp_intの変数宣言の後、mp_initで初期化が必要、ということ以外はかなり直感的な使い方が出来ることが分かる。簡単。Boost使うのに比べたらすごい簡単と思う。
mp_clear(&a);
mp_clear(&b);
mp_clear(&answer); 
mp_clear忘れてました。deleteとかfreeみたいなもんです。忘れないようにw

0 件のコメント:

コメントを投稿