C++
 Computer >> コンピューター >  >> プログラミング >> C++

C++でNaor-Reingold擬似ランダム関数を実装する方法


Naor-Reingold擬似ランダム関数は、乱数を生成するためのもう一つの強力な手法です。本記事では、その数学的な背景とアルゴリズムを解説し、実際にC++で実装する方法を紹介します。

Naor-Reingold擬似ランダム関数とは

1997年、Moni Naor(モニ・ナオール)とOmer Reingold(オメル・ラインゴールド)は、共通鍵暗号および公開鍵暗号の両分野において、さまざまな暗号プリミティブの効率的な構成方法を提唱しました。

p と l を素数とし、l | p−1(つまり l が p−1 を割り切る)であるとします。さらに、乗法位数が l である元 g ∈ Fp* を選択します。このとき、各n次元ベクトル a = (a0, a1, ..., an) に対して、次の関数が定義されます。

fa(x) = ga0 · a1^x1 · a2^x2 · … · an^xn ∈ Fp

ここで、x = x1 … xn は整数 x(0 ≤ x ≤ 2n−1)のビット表現を表します。

この関数は、対称鍵暗号、認証、デジタル署名など、多くの暗号方式の基盤として活用できることが知られています。

アルゴリズム

開始
   変数 p, l, g, n, x を宣言する
   変数 p, l, g, n の値を読み込む
   配列 a[], b[] を宣言する
   i = 0 から 10 まで繰り返す:
      x = rand() mod 16
      j = g から 0 まで繰り返す:
         b[j] = x mod 2
         x = x ÷ 2
      繰り返し終了
      mult = 1 を代入する
      k = 0 から n まで繰り返す:
         mult = mult × (pow(a[k], b[k]))
      繰り返し終了
      乱数を出力する
   繰り返し終了
終了

C++サンプルコード

#include <iostream>
using namespace std;
int main(int argc, char **argv) {
    int p = 7, l = 2, g = 3, n = 6, x;
    int a[] = { 1, 2, 2, 1 };
    int b[4];
    cout << "The Random numbers are: ";
    for (int i = 0; i < 10; i++) {
        x = rand() % 16;
        for (int j = 3; j >= 0; j--) {
            b[j] = x % 2;
            x /= 2;
        }
        int mult = 1;
        for (int k = 0; k < 6; k++)
            mult *= pow(a[k], b[k]);
        cout << pow(g, mult)<<" ";
    }
}

コードの解説

このプログラムでは、まず rand() % 16 によって 0〜15 の範囲の乱数 x を生成し、それを4桁の2進数に変換して配列 b に格納します。続いて、指数部 mult を a[0]・a[1]b[1]・… の形で計算し、最後に g の mult 乗を求めることで、Naor-Reingold関数の値を得ています。b[k] は 0 または 1 のみを取るため、mult の計算では対応する a[k] を掛けるかどうかが決まります。

実行結果

The Random numbers are: 81 81 3 9 3 81 9 9 3 9

出力を見ると、生成された値はすべて有限体 Fp の元となっており、入力のわずかな違いが異なる出力につながる様子が確認できます。これこそが擬似ランダム関数としての重要な性質です。


  1. C++でAVL木(AVLツリー)を実装する方法:回転操作とサンプルコードを徹底解説

    AVL木とは AVL木(AVL Tree)は、自己平衡型二分探索木(Self-balancing Binary Search Tree)の一種です。すべてのノードにおいて、左部分木と右部分木の高さの差が「1以下」に保たれるという性質を持っています。この平衡条件により、木が片側に偏って成長することを防ぎ、検索・挿入・削除といった操作を常に効率的(O(log n))に行うことができます。 木の回転(Tree Rotation)とは 木の回転とは、要素の順序(ソート順)を崩すことなく木の構造を変更する操作のことです。あるノードを一段上へ移動させ、別のノードを一段下へ移動させることで実現されます。 回

  2. 【C++】STLのset_symmetric_differenceで集合の対称差を実装するプログラム

    本記事では、C++の標準テンプレートライブラリ(STL)に含まれる set_symmetric_difference 関数を使って、2つの集合の「対称差」を求めるプログラムを紹介します。 対称差とは、2つの集合のうち「どちらか一方にだけ存在し、両方には存在しない」要素から構成される集合のことです。 主な集合演算の種類 和集合(Union):どちらか一方に含まれるすべての要素 積集合(Intersection):両方に共通して含まれる要素 対称差(Symmetric Difference / 排他的論理和 XOR):片方にのみ含まれる要素 差集合(Difference / 減算):一方から他方