aboutsummaryrefslogblamecommitdiffstats
path: root/sample/bls_smpl.cpp
blob: 7c08a3904e3858e141a8db7930a32e2f506cd657 (plain) (tree)
1
2
3
4
5
6
7
8
9







                                               
                                               






























                                                              



                                                                           
                           
                              






                                                              

                               
                    
                       










                                                                
                               










                                                         

                           
                              

                                              
                                     
                                          
         
                                     

                                             
                                   
                                            




































                                                                 
                                                         

































                                                                                          
#include <bls.hpp>
#include <cybozu/option.hpp>
#include <cybozu/itoa.hpp>
#include <fstream>

typedef std::vector<int> IntVec;

const std::string pubFile = "sample/publickey";
const std::string secFile = "sample/secretkey";
const std::string signFile = "sample/sign";

std::string makeName(const std::string& name, int id)
{
    const std::string suf = ".txt";
    if (id == 0) return name + suf;
    return name + cybozu::itoa(id) + suf;
}

template<class T>
void save(const std::string& file, const T& t, int id = 0)
{
    const std::string name = makeName(file, id);
    std::ofstream ofs(name.c_str(), std::ios::binary);
    if (!(ofs << t)) {
        throw cybozu::Exception("can't save") << name;
    }
}

template<class T>
void load(T& t, const std::string& file, int id = 0)
{
    const std::string name = makeName(file, id);
    std::ifstream ifs(name.c_str(), std::ios::binary);
    if (!(ifs >> t)) {
        throw cybozu::Exception("can't load") << name;
    }
}

int init()
{
    printf("make %s and %s files\n", secFile.c_str(), pubFile.c_str());
    bls::SecretKey sec;
    sec.init();
    save(secFile, sec);
    bls::PublicKey pub;
    sec.getPublicKey(pub);
    save(pubFile, pub);
    return 0;
}

int sign(const std::string& m, int id)
{
    printf("sign message `%s` by id=%d\n", m.c_str(), id);
    bls::SecretKey sec;
    load(sec, secFile, id);
    bls::Sign s;
    sec.sign(s, m);
    save(signFile, s, id);
    return 0;
}

int verify(const std::string& m, int id)
{
    printf("verify message `%s` by id=%d\n", m.c_str(), id);
    bls::PublicKey pub;
    load(pub, pubFile, id);
    bls::Sign s;
    load(s, signFile, id);
    if (s.verify(pub, m)) {
        puts("verify ok");
        return 0;
    } else {
        puts("verify err");
        return 1;
    }
}

int share(int n, int k)
{
    printf("%d-out-of-%d threshold sharing\n", k, n);
    bls::SecretKey sec;
    load(sec, secFile);
    bls::SecretKeyVec msk;
    sec.getMasterSecretKey(msk, k);
    std::vector<bls::SecretKey> secVec(n);
    for (int i = 0; i < n; i++) {
        secVec[i].set(msk, i + 1);
    }
    for (int i = 0; i < n; i++) {
        int id = secVec[i].getId();
        save(secFile, secVec[i], id);
        bls::PublicKey pub;
        secVec[i].getPublicKey(pub);
        save(pubFile, pub, id);
    }
    return 0;
}

int recover(const IntVec& ids)
{
    printf("recover from");
    for (size_t i = 0; i < ids.size(); i++) {
        printf(" %d", ids[i]);
    }
    printf("\n");
    std::vector<bls::Sign> signVec(ids.size());
    for (size_t i = 0; i < signVec.size(); i++) {
        load(signVec[i], signFile, ids[i]);
    }
    bls::Sign s;
    s.recover(signVec);
    save(signFile, s);
    return 0;
}

int main(int argc, char *argv[])
    try
{
    std::string mode;
    std::string m;
    int n;
    int k;
    int id;
    IntVec ids;

    cybozu::Option opt;
    opt.appendParam(&mode, "init|sign|verify|share|recover");
    opt.appendOpt(&n, 10, "n", ": k-out-of-n threshold");
    opt.appendOpt(&k, 3, "k", ": k-out-of-n threshold");
    opt.appendOpt(&m, "", "m", ": message to be signed");
    opt.appendOpt(&id, 0, "id", ": id of secretKey");
    opt.appendVec(&ids, "ids", ": select k id in [0, n). this option should be last");
    opt.appendHelp("h");
    if (!opt.parse(argc, argv)) {
        goto ERR_EXIT;
    }

    bls::init();

    if (mode == "init") {
        return init();
    } else if (mode == "sign") {
        if (m.empty()) goto ERR_EXIT;
        return sign(m, id);
    } else if (mode == "verify") {
        if (m.empty()) goto ERR_EXIT;
        return verify(m, id);
    } else if (mode == "share") {
        return share(n, k);
    } else if (mode == "recover") {
        if (ids.empty()) {
            fprintf(stderr, "use -ids option. ex. share -ids 1 3 5\n");
            goto ERR_EXIT;
        }
        return recover(ids);
    } else {
        fprintf(stderr, "bad mode %s\n", mode.c_str());
    }
ERR_EXIT:
    opt.usage();
    return 1;
} catch (std::exception& e) {
    fprintf(stderr, "ERR %s\n", e.what());
    return 1;
}