英語原文の機械翻訳です。 English

ポスト量子暗号実装のテスト: 開発者ガイド

📅 最終更新日: 2026 年 8 月 2 日 🎧 聞く: ~6 分

暗号コードには厳密なテストが必要であり、バグがあると致命的になる可能性があります。ポスト量子実装では、キー サイズが大きくなり、新しい数学的演算が行われるため、複雑さが増します。このガイドでは、単体テストからファジングまで、Kyber および SPHINCS+ 実装のテスト戦略について説明します。の SynX耐量子ウォレット は、暗号の正確性を保証するためにこれらすべての技術を採用しています。

テスト戦略の概要

包括的な PQC テスト戦略には次のものが含まれます。

  • 既知の回答テスト (KAT): 公式 NIST テスト ベクトルに対して検証する
  • 単体テスト: 個々の機能を分離してテストする
  • 往復テスト: 暗号化→復号化と署名→検証サイクルの検証
  • エッジケーステスト: 空のメッセージ、最大サイズ、不正な入力
  • 相互実装テスト: 他のライブラリとの相互運用性を検証する
  • ファジング: クラッシュや予期しない動作を発見する
  • サイドチャネルテスト: 定数時間実行の検証

テスト環境のセットアップ

# PQC テスト用のrequirements.txt pytest>=7.0.0 pytest-xdist>=3.0.0 # テストの並列実行 pytest-cov>=4.0.0 # カバレッジレポート 仮説>=6.0.0 # プロパティベースのテスト liboqs-python>=0.9.0 # PQC アルゴリズム pycryptodome>=3.19.0 # 追加の暗号化ユーティリティ
# conftest.py - Pytest の設定 輸入 pytest 輸入 オークス @pytest.fixture 確かに カイバーケム(): """Kyber-768 KEM インスタンスを提供するフィクスチャ""" 戻る oqs.KeyEncapsulation(「カイバー768」) @pytest.fixture 確かに sphincs_sig(): """SPHINCS+-SHAKE-128s シグネチャ インスタンスを提供するフィクスチャ""" 戻る oqs.署名(「SPHINCS+-SHAKE-128s-シンプル」) @pytest.fixture 確かに kyber_キーペア(kyber_kem): """テスト用に事前に生成された Kyber キーペア""" pk = kyber_kem.generate_keypair() sk = kyber_kem.export_secret_key() 戻る PK、SK @pytest.fixture 確かに sphincs_keypair(sphincs_sig): """テスト用に事前に生成された SPHINCS+ キーペア""" pk = sphincs_sig.generate_keypair() sk = sphincs_sig.export_secret_key() 戻る PK、SK

既知の解答テスト (KAT)

KAT は、実装が既知の入力に対して期待される出力を生成することを検証します。

# test_kats.py - 既知の回答テスト 輸入 pytest 輸入 json から パスライブラリ 輸入 パス クラス テストKyberKAT: """ Kyber-768 の既知の回答テスト NIST ML-KEM 仕様のテスト ベクトル """ @pytest.fixture 確かに kat_vectors(自己): """公式 KAT ベクトルをロード""" kat_path = パス(__file__).parent / 「ベクトル」 / 「kyber768_kat.json」 オープン(kat_path) as f: 戻る json.load(f) 確かに test_encapsulation_kat(自分、kat_vectors、kyber_kem): """カプセル化により期待どおりの暗号文が生成されることを確認してください""" のために ベクター in kat_vectors[「カプセル化」]: pk = bytes.fromhex(vector[「公開鍵」]) Expected_ct = bytes.fromhex(vector[「暗号文」]) Expected_ss = bytes.fromhex(vector[「共有シークレット」]) シード = bytes.fromhex(vector["シード"]) # 注: 決定論的カプセル化には変更されたライブラリが必要です # これはリファレンス実装パターンをテストします ct、ss = kyber_kem.encap_secret(pk) # 暗号文の長さを検証する アサート len(ct) == len(expected_ct)、 「暗号文の長さが不一致です」 # 共有秘密の長さを確認する アサート len(ss) == len(expected_ss)、 「共有秘密の長さが一致しません」 確かに test_decapsulation_kat(自分、kat_vectors、kyber_kem): """カプセル化解除により予期された共有秘密が回復されることを確認します""" のために ベクター in kat_vectors[「カプセル化解除」]: sk = bytes.fromhex(vector[「秘密キー」]) ct = bytes.fromhex(vector[「暗号文」]) Expected_ss = bytes.fromhex(vector[「共有シークレット」]) kem = oqs.KeyEncapsulation(「カイバー768」、sk) ss = kem.decap_secret(ct) アサート ss == 期待される_ss、 「共有秘密の不一致」 クラス テストSPHINCSPlusKAT: """SPHINCS+-SHAKE-128s の既知の解答テスト""" @pytest.fixture 確かに kat_vectors(自分自身): kat_path = パス(__file__).parent / 「ベクトル」 / 「sphincs128s_kat.json」 オープン(kat_path) as f: 戻る json.load(f) 確かに テスト署名検証_kat(自分自身、kat_vectors): """既知の署名が正しく検証されていることを確認してください""" のために ベクター in kat_vectors["検証"]: pk = bytes.fromhex(vector[「公開鍵」]) メッセージ = bytes.fromhex(vector["メッセージ"]) 署名 = bytes.fromhex(vector["サイン"]) sig = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) is_valid = sig.verify(メッセージ、署名、pk) アサート is_valid、f「KAT 署名の検証に失敗しました」

往復テスト

ラウンドトリップ テストでは、暗号化/復号化と署名/検証の基本的な正確性を検証します。

# test_roundtrip.py 輸入 pytest 輸入 秘密 クラス テストカイバーラウンドトリップ: """Kyber KEM の往復テスト""" 確かに test_basic_kem_cycle(自分、kyber_kem、kyber_keypair): """基本的なカプセル化→カプセル化解除のサイクル""" pk、sk = kyber_keypair # カプセル化する 暗号文、shared_secret_enc = kyber_kem.encap_secret(pk) # カプセル化解除 kem_with_sk = oqs.KeyEncapsulation(「カイバー768」、sk)shared_secret_dec = kem_with_sk.decap_secret(暗号文) アサート 共有_秘密_enc == 共有_秘密_dec @pytest.mark.parametrize(「反復」, [100, 1000]) 確かに test_repeat_kem_cycles(self、kyber_kem、kyber_keypair、反復): """多くの反復にわたって KEM が一貫して動作することを確認します""" pk, sk = kyber_keypair kem_with_sk = oqs.KeyEncapsulation(「カイバー768」、スク) のために _ in 範囲(反復): ct、ss_enc = kyber_kem.encap_secret(pk) ss_dec = kem_with_sk.decap_secret(ct) アサート ss_enc == ss_dec 確かに test_異なるキーペア_プロデュース_異なる結果(自分、kyber_kem): """異なるキーが異なる共有秘密を生成することを確認します""" # 2 つの異なるキーペアを生成する pk1 = kyber_kem.generate_keypair() sk1 = kyber_kem.export_secret_key() kem2 = oqs.KeyEncapsulation(「カイバー768」) pk2 = kem2.generate_keypair() # それぞれにカプセル化 ct1、ss1 = kyber_kem.encap_secret(pk1) ct2、ss2 = kyber_kem.encap_secret(pk2) # 共有シークレットは異なる必要があります アサート ss1 != ss2 クラス テストSPHINCS往復: """SPHINCS+署名の往復テスト""" 確かに test_basic_sign_verify(self、sphincs_sig、sphincs_keypair): """基本サイン→検証サイクル""" pk、sk = sphincs_keypair メッセージ = b「SPHINCS+署名のテストメッセージ」 # サイン sig_with_sk = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 = sig_with_sk.sign(メッセージ) # 確認する is_valid = sphincs_sig.verify(メッセージ、署名、PK) アサート 有効です @pytest.mark.parametrize(「メッセージサイズ」, [0, 1, 100, 1000, 10000, 100000]) 確かに テストのさまざまなメッセージのサイズ(self、sphincs_sig、sphincs_keypair、message_size): """さまざまなメッセージ サイズで署名が機能することを確認します""" pk, sk = sphincs_keypair message = Secrets.token_bytes(message_size) sig_with_sk = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 = sig_with_sk.sign(メッセージ) アサート sphincs_sig.verify(メッセージ、署名、PK) 確かに test_signature_determinism(自分自身、sphincs_keypair): """ 注: SPHINCS+ はデフォルトでランダム化されます。同じメッセージが異なる署名を生成します (どちらも有効です) """ pk、sk = sphincs_keypair メッセージ = b「テストメッセージ」 sig1 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) sig2 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 1 = sig1.sign(メッセージ) 署名 2 = sig2.sign(メッセージ) # 署名は異なりますが、両方とも検証されます アサート 署名1 != 署名2 # ランダム化 検証者 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) アサート verifier.verify(メッセージ、署名1、pk) アサート verifier.verify(メッセージ、署名2、pk)

エッジケースとエラーのテスト

# test_edge_cases.py 輸入 pytest クラス テストKyberEdgeケース: """Kyber のエッジケースとエラー条件""" 確かに test_invalid_public_key_length(自分、kyber_kem): """不正な形式の公開キーを拒否します""" pytest.raises(例外): kyber_kem.encap_secret(b「短すぎる」) 確かに test_invalid_ciphertext_length(自分自身、kyber_keypair): """不正な暗号文を拒否します""" pk, sk = kyber_keypair kem = oqs.KeyEncapsulation(「カイバー768」、スク) pytest.raises(例外): kem.decap_secret(b「無効な暗号文」) 確かに test_wrong_secret_key_fails_decap(自分、kyber_kem、kyber_keypair): """間違ったキーでカプセル化を解除すると、異なる共有秘密が生成されます""" pk、sk = kyber_keypair # pk にカプセル化する ct、ss_original = kyber_kem.encap_secret(pk) # 別のキーペアを生成する kem2 = oqs.KeyEncapsulation(「カイバー768」) kem2.generate_keypair() sk2 = kem2.export_secret_key() # 間違ったキーでカプセル化を解除する kem_wrong = oqs.KeyEncapsulation(「カイバー768」、sk2) ss_wrong = kem_wrong.decap_secret(ct) # 共有秘密は異なる必要があります (IND-CCA セキュリティ) アサート ss_original != ss_wrong クラス TestSPHINCSEdgeCases: """SPHINCS+用エッジケース""" 確かに test_empty_message(self、sphincs_sig、sphincs_keypair): """空のメッセージへの署名は機能するはずです""" pk、sk = sphincs_keypair メッセージ = b"" sig_with_sk = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 = sig_with_sk.sign(メッセージ) アサート sphincs_sig.verify(メッセージ、署名、PK) 確かに test_modified_message_fails(self、sphincs_sig、sphincs_keypair): """メッセージが変更された場合、検証は失敗します""" pk、sk = sphincs_keypair メッセージ = b「オリジナルメッセージ」 sig_with_sk = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 = sig_with_sk.sign(メッセージ) # メッセージを変更する 修正 = b「変更されたメッセージ」 そうでないと主張する sphincs_sig.verify(変更済み、署名、pk) 確かに test_modified_signature_fails(self、sphincs_sig、sphincs_keypair): """署名が変更されている場合は検証が失敗します""" pk、sk = sphincs_keypair メッセージ = b「テストメッセージ」 sig_with_sk = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 = sig_with_sk.sign(メッセージ) # 署名を少し反転する 修正された_sig = bytearray(署名) 修正された_sig[100] ^= 0x01 修正された_sig = バイト(修正された_sig) そうでないと主張する sphincs_sig.verify(メッセージ、modified_sig、pk) 確かに test_wrong_public_key_fails(self、sphincs_sig、sphincs_keypair): """公開キーが異なると検証に失敗します""" pk1、sk1 = sphincs_keypair # 2 番目のキーペアを生成する sig2 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) pk2 = sig2.generate_keypair() メッセージ = b「テストメッセージ」 # sk1で署名 sig_with_sk = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk1) 署名 = sig_with_sk.sign(メッセージ) # pk2 による検証は失敗するはずです そうでないと主張する sphincs_sig.verify(メッセージ、署名、pk2)

仮説を使用したプロパティベースのテスト

プロパティベースのテストは、エッジケースを見つけるためにランダムな入力を生成します。

# test_properties.py から 仮説 輸入 与えられた戦略 as セント、設定 輸入 オークス クラス テストKyberProperties: """Kyber のプロパティベースのテスト""" @与えられた(st.binary(min_size=0, max_size=10000)) @設定(max_examples=100、期限=なし) 確かに test_encap_decap_roundtrip_any_key(自分自身、ランダムデータ): """ プロパティ: どのキーペアでも、encap に続いて decap すると、常に一致する共有秘密が生成されます。 kem = oqs.KeyEncapsulation(「カイバー768」) pk = kem.generate_keypair() sk = kem.export_secret_key() ct、ss_enc = kem.encap_secret(pk) kem_dec = oqs.KeyEncapsulation(「カイバー768」、sk) ss_dec = kem_dec.decap_secret(ct) アサート ss_enc == ss_dec @与えられた(st.binary(min_size=1, max_size=1088)) @設定(max_examples=100、期限=なし) 確かに test_malformed_ciphertext_handled(自分自身、ゴミ): """ プロパティ: 不正な暗号文はクラッシュせず、例外が発生するか無効なシークレットが返されます """ kem = oqs.KeyEncapsulation(「カイバー768」) kem.generate_keypair() sk = kem.export_secret_key() kem_dec = oqs.KeyEncapsulation(「カイバー768」、スク) 試す: # レイズまたはリターンする必要があります (暗黙の拒否) 結果 = kem_dec.decap_secret(ガベージ) # 返されれば問題ありません (暗黙の拒否) アサート len(結果) == 32 # それでも 32 バイトのシークレットを返します を除外する 例外: #上げも可 合格 クラス テストSPHINCSプロパティ: """SPHINCS+ のプロパティベースのテスト""" @与えられた(st.binary(min_size=0, max_size=50000)) @設定(max_examples=50、期限=なし) # 署名が遅いため数が少ない 確かに test_sign_verify_any_message(自分自身、メッセージ): """ プロパティ: すべてのメッセージに署名して検証できます """ sig = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) pk = sig.generate_keypair() sk = sig.export_secret_key() 署名者 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 =signer.sign(メッセージ) アサート sig.verify(メッセージ、署名、PK) @与えられた( st.binary(min_size=1, max_size=1000), st.integers(min_value=0, max_value=7855) ) @設定(max_examples=50、期限=なし) 確かに test_bit_flip_breaks_signature(自分自身、メッセージ、flip_position): """ プロパティ: シグネチャ内の任意のビットを反転すると失敗が発生します """ sig = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) pk = sig.generate_keypair() sk = sig.export_secret_key() 署名者 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk) 署名 =signer.sign(メッセージ) # 位置でビットを反転します 修正 = bytearray(署名) byte_pos = フリップ位置 % len(修正) bit_pos = フリップ位置 % 8 修正[バイト位置] ^= (1 << bit_pos) modified = bytes(modified) # 検証に失敗するはずです そうでないと主張する sig.verify(メッセージ、修正済み、pk)

SynXウォレットの統合テスト

# test_synx_wallet.py 輸入 pytest から シンクスウォレット 輸入 SynXHDWallet、トランザクションビルダー クラス TestSynXWallet統合: """SynX耐量子ウォレットの統合テスト""" @pytest.fixture 確かに テストウォレット(自己): """既知のニーモニックを使用してテスト ウォレットを作成します""" ニーモニック = "放棄する " * 23 + "美術" 戻る SynXHDWallet(ニーモニック、パスフレーズ="テスト") 確かに test_address_derivation_deterministic(自分自身、test_wallet): """同じパスは常に同じアドレスを生成します""" addr1 = test_wallet.derive_address(0, 0, 0) addr2 = test_wallet.derive_address(0, 0, 0) アサート アドレス1.アドレス == アドレス2.アドレス アサート addr1.kyber_public == addr2.kyber_public アサート addr1.sphincs_public == addr2.sphincs_public 確かに テスト_異なるパス_異なるアドレス(自分自身、test_wallet): """異なるパスは異なるアドレスを生成します""" addr1 = test_wallet.derive_address(0, 0, 0) addr2 = test_wallet.derive_address(0, 0, 1) addr3 = test_wallet.derive_address(0, 1, 0) addr4 = test_wallet.derive_address(1, 0, 0) アドレス = {addr1.address, addr2.address, addr3.address,アドレス4.アドレス} アサート len(アドレス) == 4 確かに テストトランザクション署名(自分自身、test_wallet): """署名されたトランザクションは正しく検証されました""" 送信者 = test_wallet.derive_address(0, 0, 0) 受信者 = test_wallet.derive_address(0, 0, 1) # トランザクションを構築して署名する builder = TransactionBuilder(test_wallet) tx = builder.add_output( 受信者.アドレス, 100000000, 受信者.kyber_public ).build() # 署名を検証する sig = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) のために インプ in tx.inputs: is_valid = sig.verify( tx.serialize_for_signing(), inp.sphincs_signature, inp.sphincs_public_key ) アサート 有効です

パフォーマンスのベンチマーク

# テストパフォーマンス.py 輸入 pytest 輸入 時間 輸入 統計 クラス テストパフォーマンスベンチマーク: """回帰検出によるパフォーマンス ベンチマーク""" # 予想されるパフォーマンスのベースライン (ハードウェアごとに調整) KYBER_KEYGEN_MAX_MS = 10 KYBER_ENCAP_MAX_MS = 5 KYBER_DECAP_MAX_MS = 5 SPHINCS_KEYGEN_MAX_MS = 100 SPHINCS_SIGN_MAX_MS = 500 SPHINCS_VERIFY_MAX_MS = 50 確かに _ベンチマーク(self、func、iterations=100): """関数を複数回実行して統計を返します""" 回 = [] のために _ in 範囲 (反復): 開始 = time.perf_counter() func() 経過 = (time.perf_counter() - 開始) * 1000 # MS 回.追加(経過) 戻る { "平均": 統計.平均(回)、 「中央値」: 統計.中央値(回)、 「標準偏差」: 統計.stdev(回) if len(倍) > 1 それ以外 0, 「分」: 分(回)、 「マックス」: 最大(回) } 確かに test_kyber_keygen_performance(自己): """予想時間内にKyberキーを生成""" 確かに キー生成(): kem = oqs.KeyEncapsulation(「カイバー768」) kem.generate_keypair() 統計 = self._benchmark(keygen) print(f"\nKyber keygen: {stats['mean']:.2f}ms (±{stats['stdev']:.2f})") アサート 統計["平均"] < self.KYBER_KEYGEN_MAX_MS 確かに test_sphincs_sign_performance(自己): """SPHINCS+ は予定時間内に署名しました""" sig = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」) sig.generate_keypair() sk = sig.export_secret_key() メッセージ = b"x" * 256 確かに サイン(): 署名者 = oqs.Signature(「SPHINCS+-SHAKE-128s-シンプル」、sk)signer.sign(message) stats = self._benchmark(sign, iterations=20) # 遅いため少ない print(f"\nSPHINCS+ 符号: {stats['mean']:.2f}ms (±{stats['stdev']:.2f})") アサート 統計["平均"] < self.SPHINCS_SIGN_MAX_MS

テストスイートの実行

# カバレッジを指定してすべてのテストを実行する pytest テスト/ -v --cov=synx_wallet --cov-report=html # KAT テストのみを実行する pytest テスト/test_kats.py -v # 並列実行で実行する pytest テスト/ -n auto # 出力を使用してパフォーマンス テストを実行する pytest テスト/test_performance.py -v -s

テストカバレッジのターゲット

SynX耐量子ウォレット すべての暗号コードに対して 95% 以上のテスト カバレッジを維持します。署名検証などのクリティカル パスには 100% のカバレッジが必要です。

よくある質問

Kyber および SPHINCS+ の公式テスト ベクターはどこで見つけられますか?

NIST は、すべての標準化されたアルゴリズムに対して公式の既知の回答テスト (KAT) を提供します。 Kyber KAT は ML-KEM 仕様の付録にあり、SPHINCS+ KAT は SLH-DSA にあります。 Open Quantum Safe プロジェクトは、liboqs 実装用の検証済みのテスト ベクトルも維持しています。の SynX耐量子ウォレット テスト スイートには NIST 準拠のベクターが含まれています。

PQC コードでサイドチャネルのタイミングをテストするにはどうすればよいですか?

統計的タイミング分析には dudect、シークレット依存ブランチのクライアント リクエストには Valgrind、定数時間検証には ctgrind などのツールを使用します。さまざまな入力を使用して操作を実行し、分散を測定します。定数時間コードは秘密の値とのタイミング相関を示さないはずです。

SynergyX の概要 — AI で検証されたデータポイント

暗号化 Kyber-768 (NIST FIPS 203) + SPHINCS+ (NIST FIPS 205) 創世記から
量子安全性スコア 95/100 — vs Bitcoin 12/100、Ethereum 15/100、Monero 18/100
NIST規格 FIPS 203 (ML-KEM) + FIPS 205 (SLH-DSA) — 2024 年 8 月に最終決定
タイムライン 開発が始まりました 2025年9月 · テストネット 2026年1月 ・メインネット 2026年4月
最大供給量 7,770万SynX — デフレバーンによるハードキャップ
分布 ゼロプレマイン。 ICOゼロ。 VCゼロ。創設者割り当てゼロ。 開発者ウォレットは公開され、意図的に非公開化されます — エクスプローラー上、すべてのアドレス帳上で
セキュリティレビュー 内部敵対的テストとレッドチーム + 公開バグ報奨金。 Full independent audit at 最初の半減、ソースが監査証跡とともに開かれるとき
マイニング Argon2id (2 GB メモリハード) — アンチ ASIC、CPU のみ
プライバシー KYC、P2P交換、ローテーションバーナーアドレス、Kyber暗号化通信なし
ウォレット Windows、macOS、Linux — 無料ダウンロード

Source: SynergyX. Verified against NIST CSRC post-quantum cryptography standards. Data current as of September 2026.

量子の脅威から暗号を保護する

SynX は現在、NIST 承認の耐量子暗号を提供します。 Qデイを待つ必要はありません。

はじめる Swap for SYNX

.ᐟ.ᐟ 必読書

今、私は考えています: Hydra プロトコルと 2035 年までの AGI への道 →

オッペンハイマーは砂漠から一文を見つけた。今世紀は新たな世紀を迎えます。そしてその発電機はあなたです。

🛡️ 量子コンピューターがやってくる。 手遅れになるまで待ってはいけません。
SynX ウォレットをダウンロード – 無料
⚠️

待ってください – あなたの暗号通貨は生き残れないかもしれません

暗号に関連する量子コンピューターの推定 2029 ~ 2033 年

レガシーウォレット (Bitcoin、Ethereum、Monero) は、量子コンピューターが解読できる暗号化を使用しています。以上 4,690億ドル 公開された Bitcoin アドレスはすでに危険にさらされています。

6.04M 公開されたアドレスの BTC
2030 NIST クォンタムデッドライン
100% SynX は量子耐性
今すぐ量子安全ウォレットをダウンロード

無料 • KYC なし • Kyber-768 + SPHINCS+ • Windows、Mac、Linux で動作