首页 > 解决方案 > 未知:此对象不支持多通道,当使用 SecretSharing 时

问题描述

我正在使用 Crypto++ 的SecretSharing类。我想将共享(假设它是 n 个共享)除以SecretSharingn 个字符串对象,然后打印结果。但是我的程序总是抛出异常。我能做些什么来避免它?

    #include<iostream>//using cout、cin 
    #include<filters.h>
    #include<files.h>
    #include<osrng.h>
    #include<ida.h>
    #include<channels.h>
    #include<randpool.h>
    #include<string>
    #include<hex.h>
    using namespace std;
    using namespace CryptoPP;

    int main()
    {

    try
    {
        AutoSeededRandomPool rng;
        string message = "I like Cryptopgraphy.";
        string Share1,Share2,Share3,Share4,tmp;
        StringSink S1(Share1);
        StringSink S2(Share2);
        StringSink S3(Share3);
        StringSink S4(Share4);
        ChannelSwitch* channelSwitch = new ChannelSwitch;
        channelSwitch->AddDefaultRoute(S1);
        channelSwitch->AddDefaultRoute(S2);
        channelSwitch->AddDefaultRoute(S3);
        channelSwitch->AddDefaultRoute(S4);
        StringSource Src(message,true,new SecretSharing(rng,2,4,channelSwitch));
        cout << "Share1:" << Share1 << endl;
        cout << "Share2:" << Share2 << endl;
        cout << "Share3:" << Share3 << endl;
        cout << "Share4:" << Share4 << endl;
    }
    catch(const Exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;
}

例外是:

unknown: this object doesn't support multiple channels*

我还有一个关于ChannelSwitch. SecretSharingCrypto++ 的手册说“ChannelSwitch 可以根据通道 ID 将输入路由到不同和/或多个通道。”

  1. 如何设置频道的 ID?

  2. 它可以将一个输入路由到多个输出通道吗?

  3. 它可以将多个输入路由到一个输出通道吗?

谁能给我一些关于上述问题的例子。

标签: c++cryptographycrypto++

解决方案


我找到了这些代码,但我不明白一些代码的含义。例如,下面的代码。


        while (strSources[0]->Pump(256))
        {
            for (unsigned int i=1; i<threshold; i++)
                strSources[i]->Pump(256);
        }

        for (unsigned int i=0; i<threshold; i++)
            strSources[i]->PumpAll();

为什么让每个 Source 每次抽 256 个字节?为什么不让他们一次性抽取所有数据?

  // Information Dispesal and Secret Sharing
    bool TestSharing()
    {
    std::cout << "\nInformation Dispersal and Secret Sharing...\n\n";
    static const unsigned int INFORMATION_SHARES = 128;
    static const unsigned int SECRET_SHARES = 64;
    static const unsigned int CHID_LENGTH = 4;
    bool pass=true, fail=false;

    // ********** Infrmation Dispersal **********//

    for (unsigned int shares=3; shares<INFORMATION_SHARES; ++shares)
    {
        std::string message;
        unsigned int len = GlobalRNG().GenerateWord32(4, 0xff);
        unsigned int threshold = GlobalRNG().GenerateWord32(2, shares-1);

        RandomNumberSource(GlobalRNG(), len, true, new StringSink(message));

        ChannelSwitch *channelSwitch = NULLPTR;
        StringSource source(message, false, new InformationDispersal(threshold, 
          shares, channelSwitch = new ChannelSwitch));

        std::vector<std::string> strShares(shares);
        vector_member_ptrs<StringSink> strSinks(shares);
        std::string channel;

        // ********** Create Shares
        for (unsigned int i=0; i<shares; i++)
        {
            strSinks[i].reset(new StringSink(strShares[i]));
            channel = WordToString<word32>(i);
            strSinks[i]->Put((const byte *)channel.data(), CHID_LENGTH);
            channelSwitch->AddRoute(channel, *strSinks[i], DEFAULT_CHANNEL);
        }
        source.PumpAll();

        // ********** Randomize shares

        GlobalRNG().Shuffle(strShares.begin(), strShares.end());

        // ********** Recover secret
        try
        {
            std::string recovered;
            InformationRecovery recovery(threshold, new StringSink(recovered));

            vector_member_ptrs<StringSource> strSources(threshold);
            channel.resize(CHID_LENGTH);

            for (unsigned int i=0; i<threshold; i++)
            {
                strSources[i].reset(new StringSource(strShares[i], false));
                strSources[i]->Pump(CHID_LENGTH);
                strSources[i]->Get((byte*)&channel[0], CHID_LENGTH);
                strSources[i]->Attach(new ChannelSwitch(recovery, channel));
            }

            while (strSources[0]->Pump(256))
            {
                for (unsigned int i=1; i<threshold; i++)
                    strSources[i]->Pump(256);
            }

            for (unsigned int i=0; i<threshold; i++)
                strSources[i]->PumpAll();

            fail = (message != recovered);
        }
        catch (const Exception&)
        {
            fail = true;
        }

        pass &= !fail;
    }

    std::cout << (fail ? "FAILED:" : "passed:") << "  " << INFORMATION_SHARES << " 
         information dispersals\n";

    // ********** Secret Sharing **********//

    for (unsigned int shares=3; shares<SECRET_SHARES; ++shares)
    {

        std::string message;
        unsigned int len = GlobalRNG().GenerateWord32(4, 0xff);
        unsigned int threshold = GlobalRNG().GenerateWord32(2, shares-1);

        RandomNumberSource(GlobalRNG(), len, true, new StringSink(message));

        ChannelSwitch *channelSwitch = NULLPTR;
        StringSource source(message, false, new SecretSharing(GlobalRNG(), 
           threshold, shares, channelSwitch = new ChannelSwitch));

        std::vector<std::string> strShares(shares);
        vector_member_ptrs<StringSink> strSinks(shares);
        std::string channel;

        // ********** Create Shares
        for (unsigned int i=0; i<shares; i++)
        {
            strSinks[i].reset(new StringSink(strShares[i]));
            channel = WordToString<word32>(i);
            strSinks[i]->Put((const byte *)channel.data(), CHID_LENGTH);
            channelSwitch->AddRoute(channel, *strSinks[i], DEFAULT_CHANNEL);
        }
        source.PumpAll();

        // ********** Randomize shares

        GlobalRNG().Shuffle(strShares.begin(), strShares.end());

        // ********** Recover secret
        try
        {
            std::string recovered;
            SecretRecovery recovery(threshold, new StringSink(recovered));

            vector_member_ptrs<StringSource> strSources(threshold);
            channel.resize(CHID_LENGTH);
            for (unsigned int i=0; i<threshold; i++)
            {
                strSources[i].reset(new StringSource(strShares[i], false));
                strSources[i]->Pump(CHID_LENGTH);
                strSources[i]->Get((byte*)&channel[0], CHID_LENGTH);
                strSources[i]->Attach(new ChannelSwitch(recovery, channel));
            }

            while (strSources[0]->Pump(256))
            {
                for (unsigned int i=1; i<threshold; i++)
                    strSources[i]->Pump(256);
            }

            for (unsigned int i=0; i<threshold; i++)
                strSources[i]->PumpAll();

            fail = (message != recovered);
        }
        catch (const Exception&)
        {
            fail = true;
        }

        pass &= !fail;
    }

    std::cout << (fail ? "FAILED:" : "passed:") << "  " << SECRET_SHARES << " 
       secret sharings\n";

    return pass;
}

推荐阅读