2017-12-17 22 views
2

私はWikipediaのエントリーを含め、私が遭遇することができた盲目の署名に関するホワイトペーパーと仕様を読んだことがありますが、これらは背後にある数学的理論に焦点を当てる傾向があります。Crypto ++でブラインドRSAシグネチャを作成および検証する方法

C++内で、Crypto ++ライブラリを使用してRSAブラインド署名を簡潔に実装していますか?

答えて

2

C++では、Crypto ++ライブラリを使用して、RSAブラインドシグネチャを簡潔に実装していますか?

はい。 Crypto ++ Wikiには、RSAの盲目的な署名に関するセクションがRaw RSA | RSA Blind Signatureにあります。以下はwikiから取ったコードです。

Crypto ++には盲目の署名クラスがありません。以下の方法は、Blind Signaturesで説明されている基本アルゴリズムに従います。ただし、Wikipediaとの相違点は、s(s'(x)) = xクロスチェックを適用することです。クロスチェックはChaum's original paperにありましたが、wikiの記事にはありません。 Chaumの論文とウィキペディアの2つ目の違いは、以下のコードはmではなくH(m)です。これはRabin in 1979に起因します。

私たちが知る限り、署名方式をカバーする標準はありません。標準化の欠如は確実にinteropの問題を引き起こすでしょう。たとえば、以下のコードではSHA256を使用して署名対象のメッセージをハッシュし、RSA Blind Signature Scheme for golangでは完全なドメインハッシュを使用しています。 Crypto.SEのIs there a standard padding/format for RSA Blind Signatures?も参照してください。

最初にUsability of padding scheme in blinded RSA signature?またはRSA blind signatures in practiceに応じてパディング機能を適用することができます。ここで


#include "cryptlib.h" 
#include "integer.h" 
#include "nbtheory.h" 
#include "osrng.h" 
#include "rsa.h" 
#include "sha.h" 
using namespace CryptoPP; 

#include <iostream> 
#include <stdexcept> 
using std::cout; 
using std::endl; 
using std::runtime_error; 

int main(int argc, char* argv[]) 
{ 
    // Bob artificially small key pair 
    AutoSeededRandomPool prng; 
    RSA::PrivateKey privKey; 

    privKey.GenerateRandomWithKeySize(prng, 64); 
    RSA::PublicKey pubKey(privKey); 

    // Convenience 
    const Integer& n = pubKey.GetModulus(); 
    const Integer& e = pubKey.GetPublicExponent(); 
    const Integer& d = privKey.GetPrivateExponent(); 

    // Print params 
    cout << "Pub mod: " << std::hex << pubKey.GetModulus() << endl; 
    cout << "Pub exp: " << std::hex << e << endl; 
    cout << "Priv mod: " << std::hex << privKey.GetModulus() << endl; 
    cout << "Priv exp: " << std::hex << d << endl; 

    // For sizing the hashed message buffer. This should be SHA256 size. 
    const size_t SIG_SIZE = UnsignedMin(SHA256::BLOCKSIZE, n.ByteCount()); 

    // Scratch 
    SecByteBlock buff1, buff2, buff3; 

    // Alice original message to be signed by Bob 
    SecByteBlock orig((const byte*)"secret", 6); 
    Integer m(orig.data(), orig.size()); 
    cout << "Message: " << std::hex << m << endl; 

    // Hash message per Rabin (1979) 
    buff1.resize(SIG_SIZE); 
    SHA256 hash1; 
    hash1.CalculateTruncatedDigest(buff1, buff1.size(), orig, orig.size()); 

    // H(m) as Integer 
    Integer hm(buff1.data(), buff1.size()); 
    cout << "H(m): " << std::hex << hm << endl; 

    // Alice blinding 
    Integer r; 
    do { 
     r.Randomize(prng, Integer::One(), n - Integer::One()); 
    } while (!RelativelyPrime(r, n)); 

    // Blinding factor 
    Integer b = a_exp_b_mod_c(r, e, n); 
    cout << "Random: " << std::hex << b << endl; 

    // Alice blinded message 
    Integer mm = a_times_b_mod_c(hm, b, n); 
    cout << "Blind msg: " << std::hex << mm << endl; 

    // Bob sign 
    Integer ss = privKey.CalculateInverse(prng, mm); 
    cout << "Blind sign: " << ss << endl; 

    // Alice checks s(s'(x)) = x. This is from Chaum's paper 
    Integer c = pubKey.ApplyFunction(ss); 
    cout << "Check sign: " << c << endl; 
    if (c != mm) 
     throw runtime_error("Alice cross-check failed"); 

    // Alice remove blinding 
    Integer s = a_times_b_mod_c(ss, r.InverseMod(n), n); 
    cout << "Unblind sign: " << s << endl; 

    // Eve verifies 
    Integer v = pubKey.ApplyFunction(s);  
    cout << "Verify: " << std::hex << v << endl; 

    // Convert to a string 
    size_t req = v.MinEncodedSize(); 
    buff2.resize(req); 
    v.Encode(&buff2[0], buff2.size()); 

    // Hash message per Rabin (1979) 
    buff3.resize(SIG_SIZE); 
    SHA256 hash2; 
    hash2.CalculateTruncatedDigest(buff3, buff3.size(), orig, orig.size()); 

    // Constant time compare 
    bool equal = buff2.size() == buff3.size() && VerifyBufsEqual(
     buff2.data(), buff3.data(), buff3.size()); 

    if (!equal) 
     throw runtime_error("Eve verified failed"); 

    cout << "Verified signature" << endl; 

    return 0; 
} 

建物の結果であり、プログラムを実行している:

$ g++ blind.cxx ./libcryptopp.a -o blind.exe 
$ ./blind.exe 
Pub mod: b55dc5e79993680fh 
Pub exp: 11h 
Priv mod: b55dc5e79993680fh 
Priv exp: 1b4fc70ff2e97f1h 
Message: 736563726574h 
H(m): 2bb80d537b1da3e3h 
Random: 72dd6819f0fc5e5fh 
Blinded msg: 27a2e2e5e6f4fbfh 
Blind sign: 84e7039495bf0570h 
Check sign: 27a2e2e5e6f4fbfh 
Unblind sign: 61054203e843f380h 
Verify: 2bb80d537b1da3e3h 
Verified signature 
関連する問題