インテル® クリプトグラフィー・プリミティブ・ライブラリーでポスト量子セキュリティーに備える

インテル® IPPセキュリティー暗号化

この記事は、インテルのウェブサイトで公開されている「Be Ready for Post-Quantum Security with Intel® Cryptography Primitives Library」の日本語参考訳です。原文は更新される可能性があります。原文と翻訳文の内容が異なる場合は原文を優先してください。


この記事の PDF 版はこちらからご利用になれます。

暗号の重要性

通信 (メッセンジャー)、金融、医療など、日常生活でデジタル技術が広く使用されている現代において、暗号は非常に重要です。暗号は、情報が簡単に傍受、操作、または盗難される可能性がある環境で、データを保護し、プライバシー、整合性、および信頼性を確保する手段を提供します。暗号化/復号化、デバイスキー認証、およびデジタル署名を使用して、個人データを保護し、データの信頼性を確認するのに役立ちます。

ポスト量子コンピューティングの世界の課題

ポスト量子暗号は、量子コンピューターが実用化された後も、信頼できる安全なセキュリティー手法を構築する取り組みです。この考え方の根底にあるのは、量子コンピューターであっても、ポスト量子暗号を現実的な時間内に解読することは不可能だろうという仮説です。

RSA や ECC (楕円曲線暗号) など、現在使用されている多くの暗号、データ認証、データ整合性を用いた手法のセキュリティーは、整数因数分解や離散対数などの特定の数学問題を解くことの難しさに依存しています。これらの問題は、従来のコンピューターでは制約された時間内に解くことが事実上不可能であり、これがこれらの手法を実質的に破ることができない理由となっています。

しかし、この状況は変わりつつあります。量子コンピューターは、ショアのアルゴリズム (Shor’s Algorithm) やその他の派生アルゴリズムを使用して、これらの問題をより効率良く解く可能性があります。新しいアルゴリズムは、RSA や ECC、デジタル署名暗号で使用される素数の特定プロセスを指数関数的に高速化できるため、インターネット通信や機密データのストレージに依存している一般的な暗号化手法は時代遅れとなり、データはもはや安全ではなくなるでしょう。

未来を見据えたソリューションの開発

暗号研究者は、量子コンピューターの使用とその特定の種類の数学問題を迅速に解く能力が将来もたらす脅威に対抗するため、新しいタイプのセキュリティーに取り組んでいます。目的は明確です。量子コンピューターが得意とする数学の問題に依存しない、新しいタイプの暗号化と復号化ベースのセキュリティーを開発することです。

新しい手法は、量子コンピューターでも解くのが困難な種類の難しい問題を使用します。高度な格子乗算とハッシュベースのアルゴリズムは、量子コンピューターの進化に先んじる一般的なアプローチです。

ポスト量子アルゴリズムは、従来の暗号アルゴリズムと同様に、さまざまなユースケースにおいて重要になります。

すでに実世界に導入されている使用例の 1 つに、Apple の iMessage モバイル・メッセージ・サービスで使用されている PQ3 ポスト量子暗号プロトコル (英語) があります。

NIST (英語) は、身元確認と認証関連のセキュリティー・サービスを専門とするフランスの多国籍テクノロジー企業である IDEMEA (英語) と協力して、銀行アプリケーション向けのポスト量子プロトコルを特定し、第 4 回 NIST PQC 標準化会議 (英語) でその推奨事項を発表しました。この取り組みは、多くの他の貢献と合わせて、NIST のポスト量子暗号 PQC (英語) の一環として、NIST がサポートする最初の 3 つのポスト量子暗号化標準 (英語) のリリースにつながりました。

量子コンピューターが普及する前に業界でポスト量子手法を統合することは、フォワード・シークレシーの確立に必要です。「遡及的復号化」の脅威とは、以前に傍受および記録された暗号化通信を後に復号化できる可能性を指します。従来の方法で暗号化されたデータは、新しい復号化技術の登場を見越して収集され、保存されることを想定しなければなりません。「遡及的復号化」のリスクを最小限に抑えるため、将来を見据えたセキュリティー体制を確立することが重要です。

図 1 は理想的な状況を示しています。暗号化アプリケーションは、最初の大規模な量子コンピューターが構築されるずっと前に、ポスト量子暗号への移行を開始すべきです。

図 1: ポスト量子暗号タイムライン

NIST のコンペティションで選択された最初の 3 つのアルゴリズム以外は現在も研究段階にあるため、ハイブリッド・モードで移行することを推奨します。「ハイブリッド」とは、古典的な暗号方式とポスト量子暗号方式を組み合わせたものです。

例えば、単一の Kyber512X 鍵合意を作成する 2 つの暗号化コンポーネントを組み合わせることができます。

  1. Kyber512: 暗号解析攻撃と量子コンピューター攻撃に耐性のあるポスト量子鍵カプセル化メカニズム
  2. X25519: 古典的な暗号化鍵合意方式

ハイブリッドを使用する利点は、Kyber512 が破られたとしても、非量子攻撃者に対してデータの安全性が維持されることです。

セキュリティーはアルゴリズムだけでなく実装にも依存することに留意しなければなりません。Kyber512 は完全な安全性をもたらすかもしれませんが、実装がサイドチャネルを介して漏洩する可能性があります。欠点は、2 つの鍵交換が実行されるため、通信により多くの CPU サイクルとフットプリントを要することですが、暗号化においてはセキュリティーが最優先されます。

インテル® クリプトグラフィー・プリミティブ・ライブラリーの概要

インテル® クリプトグラフィー・プリミティブ・ライブラリー (英語) は、インテルの各種 CPU 向けに高度に最適化されている、安全で高速、かつ軽量な暗号化ビルディング・ブロックです。

GitHub (英語) から入手できます。

多くの暗号化ドメインをサポート

インテル® クリプトグラフィー・プリミティブ・ライブラリーは、暗号化操作によく使用される次のようなルーチン群を提供します。

インテル® クリプトグラフィー・プリミティブ・ライブラリーを使用する利点

  • セキュリティー (秘密処理関数の定数時間実行)
  • 小さなフットプリント・サイズ向けに設計
  • インテルの各種 CPU および命令セット・アーキテクチャー向けに最適化 (ハードウェア暗号化命令のサポートを含む):
    • インテル® ストリーミング SIMD 拡張命令 2 (インテル® SSE2)
    • インテル® ストリーミング SIMD 拡張命令 3 (インテル® SSE3)
    • インテル® ストリーミング SIMD 拡張命令 4.2 (インテル® SSE4.2)
    • インテル® アドバンスト・ベクトル・エクステンション (インテル® AVX)
    • インテル® アドバンスト・ベクトル・エクステンション 2 (インテル® AVX2)
    • インテル® アドバンスト・ベクトル・エクステンション 512 (インテル® AVX-512)
  • パフォーマンスを最大限に引き出す構成可能な CPU ディスパッチ
  • カーネルモードの互換性
  • スレッドセーフ設計

インテル® クリプトグラフィー・プリミティブ・ライブラリーは、FIPS 140-3 準拠 (英語) のビルディング・ブロック (セルフテスト、サービス) をサポートします。

インテル® クリプトグラフィー・プリミティブ・ライブラリーのポスト量子暗号アルゴリズム

現在、インテル® クリプトグラフィー・プリミティブ・ライブラリーは、eXtended Merkle Signature Scheme (XMSS) と Leighton-Micali Signature (LMS) によるデジタル署名の検証をサポートしています。これらはステートフルなハッシュベース署名方式であり、NIST (NIST SP 800-208 (英語)) によって標準化されています。

注:
従来のデジタル署名方式とは異なり、ステートフルな署名方式では、必要な署名チェックごとに秘密鍵を更新する必要があります。ステートフルなハッシュベース署名方式では、署名に使用したワンタイム鍵の状態を保持し、それらが再利用されないことを保証する必要があります。

これらのアルゴリズムは、インテル® クリプトグラフィー・プリミティブ・ライブラリーでプレビュー機能として実装されています。

XMSS 暗号と LMS 暗号の使用

インテル® クリプトグラフィー・プリミティブ・ライブラリーのドキュメントでは、次のアルゴリズムの詳しい使用例が提供されています。

  1. XMSS 署名検証方式
  2. LMS 署名検証方式

ライブラリー実装は、アルゴリズムの呼び出しに必要なゲッターやセッターなどの特別な関数を提供します。

ECDSA 検証と LMS 検証の使用方法の比較

以下は、インテル® クリプトグラフィー・プリミティブ・ライブラリー実装の楕円曲線デジタル署名方式 (ECDSA) 検証方式と Leighton-Micali Signature (LMS) 検証方式の使用方法を比較した例です。

#include <stdlib>
#include "ippcp.h"

/* public key */
const char* pHexGx   = "...";
const char* pHexGy   = "...";
/* message */
Ipp8u pMsgDigest[]   = "...";
/* signature */
const char* pHexSigR = "...";
const char* pHexSigS = "...";
const unsigned int bitSize = 256;

IppStatus sts = ippStsNoErr;
IppECResult vfyResult = IppECResult::ippECInvalidSignature;

Ipp8u* buffer = NULL;
IppsGFpState* gf = NULL;
IppsGFpECState* ec = NULL;
IppsGFpECPoint* regPublic = NULL;
IppsGFpElement* pubGx = NULL;
IppsGFpElement* pubGy = NULL;

/* Initialize p256r1 elliptic curve */
int size = 0;
sts = ippsGFpGetSize(bitSize, &size);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

gf  = (IppsGFpState *)(new Ipp8u[size]);
sts = ippsGFpInitFixed(bitSize, ippsGFpMethod_p256r1(), gf);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

sts = ippsGFpECGetSize(gf, &size);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

ec  = (IppsGFpECState *)(new Ipp8u[size]);
sts = ippsGFpECInitStd256r1(gf, ec);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

sts = ippsGFpECBindGxyTblStd256r1(ec);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

const BigNumber Gx(pHexGx);
const BigNumber Gy(pHexGy);
const BigNumber SigR(pHexSigR);
const BigNumber SigS(pHexSigS);

/* public key Gx|Gy */
pubGx = newGFpElement(gf, Gx.DwordSize(), Gx.DataRef());
pubGy = newGFpElement(gf, Gy.DwordSize(), Gy.DataRef());

int buffSize = 0;
sts = ippsGFpECPointGetSize(ec, &buffSize);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

regPublic = (IppsGFpECPoint*)( new Ipp8u [buffSize] );
sts = ippsGFpECPointInit(pubGx, pubGy, regPublic, ec);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

sts = ippsGFpECScratchBufferSize(2, ec, &buffSize);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

buffer = (Ipp8u*)( new Ipp8u [buffSize] );

sts = ippsGFpECVerifyDSA(pMsgDigest, regPublic, SigR, SigS, &
vfyResult, ec, buffer);
if (ippStsNoErr != sts) goto CLEAR_MEMORY;

CLEAR_MEMORY:
    deleteGFpElement(pubGx);
    deleteGFpElement(pubGy);
    deleteGFpECPoint(regPublic);
    deleteGFpEC(ec);
    deleteGFp(gf);
    delete [] buffer;

if((IppECResult::ippECValid == vfyResult) &
&
 (ippStsNoErr == sts))
    std::cout << "Signature verification is ok";
else
    std::cout << "Signature verification failed";
#include <stdlib>
#include "ippcp.h"

Ipp32u q = 0x00000009;
IppsLMOTSAlgo lmotsAlgo = IppsLMOTSAlgo::LMOTS_SHA256_N32_W8; //0x00000004
IppsLMSAlgo lmsAlgo     = IppsLMSAlgo::LMS_SHA256_M32_H5;     //0x00000005
Ipp8u pI[]              = { ... };
Ipp8u pK[]              = { ... };
Ipp8u pMsg[]            = { ... };
Ipp32s msgLength        = sizeof(kat_msg);
Ipp8u pC[]         = { ... };
Ipp8u pY[]         = { ... };
Ipp8u pAuthPath[]  = { ... };
IppStatus sts;

int is_valid = 0;

/* Public key initialization */
const IppsLMSAlgoType lmsAlgTypePk = { lmotsAlgo, lmsAlgo };

int buffSize;
sts = ippsLMSBufferGetSize(&
buffSize, msgLength, lmsAlgTypePk);
if(ippStsNoErr != sts) goto CLEAR_MEMORY;
Ipp8u* pScratchBuffer = new Ipp8u[buffSize];

int ippcpPubKeySize;
sts = ippsLMSPublicKeyStateGetSize(&
ippcpPubKeySize, lmsAlgTypePk);
if(ippStsNoErr != sts) goto CLEAR_MEMORY;
IppsLMSPublicKeyState* pPubKey = new Ipp8u[ippcpPubKeySize];

sts = ippsLMSSetPublicKeyState(lmsAlgTypePk, pI, pK, pPubKey);
if(ippStsNoErr != sts) goto CLEAR_MEMORY;

/* Signature initialization */
const IppsLMSAlgoType lmsAlgTypeSig = { lmotsAlgo, lmsAlgo };
int sigBuffSize;
sts = ippsLMSSignatureStateGetSize(&
sigBuffSize, lmsAlgTypeSig);
if(ippStsNoErr != sts) goto CLEAR_MEMORY;
IppsLMSSignatureState* pSignature = new Ipp8u[sigBuffSize];

sts = ippsLMSSetSignatureState(lmsAlgTypeSig, q, pC, pY, pAuthPath, pSignature);
if(ippStsNoErr != sts) goto CLEAR_MEMORY;

/* Verification */
sts = ippsLMSVerify(pMsg, msgLength, pSignature, &
is_valid, pPubKey, pScratchBuffer);
if(ippStsNoErr != sts) goto CLEAR_MEMORY;

CLEAR_MEMORY:
    delete[] pScratchBuffer;
    delete[] pPubKey;
    delete[] pSignature;

if(is_valid &
&
 (ippStsNoErr == sts))
    std::cout << "Signature verification is ok";
else
    std::cout << "Signature verification failed";




















図 2: ECDSA 検証方式と LMS 検証方式の比較

注:
インテル® クリプトグラフィー・プリミティブ・ライブラリーの GitHub リポジトリ― (英語) で詳細な LMS の使用例を確認できます。

ポスト量子セキュリティーをアプリケーションに追加

インテル® クリプトグラフィー・プリミティブ・ライブラリーは、XMSS (eXtended Merkle Signature Scheme) と LMS Leighton-Micali Signature ハッシュベース暗号方式をサポートすることで、すでにポスト量子セキュリティーを提供しています。

インテルは、最新のポスト量子暗号技術の実装の最前線におり、NIST のポスト量子暗号 PQC (英語) 標準化の進化を注意深く監視しています。

私たちと一緒に、機密性の高い重要なデータと未来をより安全なものにしましょう。

インテル® クリプトグラフィー・プリミティブ・ライブラリーは、スタンドアロン (英語) またはインテル® oneAPI ベース・ツールキットの一部としてダウンロードできます。

ポスト量子アルゴリズムのサポートに関するご質問やご要望は、GitHub (英語) またはオンライン・サービス・センターからお寄せください。

皆様からのフィードバックとご提案をお待ちしております。

関連情報

チュートリアル

NIST のポスト量子暗号標準化

インテル® クリプトグラフィー・プリミティブ・ライブラリーのポスト量子暗号


製品および性能に関する情報

1 性能は、使用状況、構成、その他の要因によって異なります。詳細については、http://www.intel.com/PerformanceIndex/ (英語) を参照してください。

タイトルとURLをコピーしました