#include #include #include template void write(const T& t) { std::cout << std::hex << std::showbase << t << std::endl; } template void read(T& t) { if (!(std::cin >> t)) { throw std::runtime_error("can't read"); } } void strip(std::string& str) { if (str.empty()) return; if (str[str.size() - 1] == '\n') str.resize(str.size() - 1); } void readMessage(std::string& str) { str.clear(); std::string line; std::getline(std::cin, line); // remove first blank line while (std::getline(std::cin, line)) { if (!str.empty()) str += '\n'; str += line; } strip(str); if (!str.empty()) return; throw std::runtime_error("readMessage:message is empty"); } bool g_verbose = false; void init() { if (g_verbose) fprintf(stderr, "init\n"); bls::SecretKey sec; sec.init(); write(sec); } void pubkey() { if (g_verbose) fprintf(stderr, "pubkey\n"); bls::SecretKey sec; read(sec); if (g_verbose) std::cerr << "sec:" << sec << std::endl; bls::PublicKey pub; sec.getPublicKey(pub); if (g_verbose) std::cerr << "pub:" << pub << std::endl; write(pub); } void sign() { if (g_verbose) fprintf(stderr, "sign\n"); bls::SecretKey sec; read(sec); if (g_verbose) std::cerr << "sec:" << sec << std::endl; std::string m; readMessage(m); if (g_verbose) fprintf(stderr, "message:`%s`\n", m.c_str()); bls::Sign s; sec.sign(s, m); write(s); } void verify() { if (g_verbose) fprintf(stderr, "verify\n"); bls::Sign s; read(s); if (g_verbose) std::cerr << "sign:" << s << std::endl; bls::PublicKey pub; read(pub); if (g_verbose) std::cerr << "pub:" << pub << std::endl; std::string m; readMessage(m); if (g_verbose) fprintf(stderr, "message:`%s`\n", m.c_str()); bool b = s.verify(pub, m); write(b ? "1" : "0"); } void share_pub() { if (g_verbose) fprintf(stderr, "share_pub\n"); size_t k; read(k); if (g_verbose) fprintf(stderr, "k:%d\n", (int)k); bls::PublicKeyVec mpk(k); for (size_t i = 0; i < k; i++) { read(mpk[i]); } bls::Id id; read(id); if (g_verbose) std::cerr << "id:" << id << std::endl; bls::PublicKey pub; pub.set(mpk, id); write(pub); } void recover_sig() { if (g_verbose) fprintf(stderr, "recover_sig\n"); size_t k; read(k); if (g_verbose) fprintf(stderr, "k:%d\n", (int)k); bls::SignatureVec sVec(k); bls::IdVec idVec(k); for (size_t i = 0; i < k; i++) { read(idVec[i]); read(sVec[i]); } bls::Sign s; s.recover(sVec, idVec); write(s); } void aggregate_pub() { if (g_verbose) fprintf(stderr, "aggregate_pub\n"); size_t n; read(n); if (n == 0) throw std::runtime_error("aggregate_pub:n is zero"); if (g_verbose) fprintf(stderr, "n:%d\n", (int)n); bls::PublicKey pub; read(pub); if (g_verbose) std::cerr << "pub:" << pub << std::endl; for (size_t i = 1; i < n; i++) { bls::PublicKey rhs; read(rhs); pub.add(rhs); } write(pub); } void aggregate_sig() { if (g_verbose) fprintf(stderr, "aggregate_sig\n"); size_t n; read(n); if (n == 0) throw std::runtime_error("aggregate_sig:n is zero"); if (g_verbose) fprintf(stderr, "n:%d\n", (int)n); bls::Sign s; read(s); if (g_verbose) std::cerr << "sign:" << s << std::endl; for (size_t i = 1; i < n; i++) { bls::Sign rhs; read(rhs); s.add(rhs); } write(s); } int main(int argc, char *argv[]) try { const struct CmdTbl { const char *name; void (*exec)(); } tbl[] = { { "init", init }, { "pubkey", pubkey }, { "sign", sign }, { "verify", verify }, { "share-pub", share_pub }, { "recover-sig", recover_sig }, { "aggregate-pub", aggregate_pub }, { "aggregate-sig", aggregate_sig }, }; std::string cmdCat; for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { if (i > 0) cmdCat += '|'; cmdCat += tbl[i].name; } std::string mode; cybozu::Option opt; opt.appendParam(&mode, cmdCat.c_str()); opt.appendBoolOpt(&g_verbose, "v", ": verbose"); opt.appendHelp("h"); if (!opt.parse(argc, argv)) { goto ERR_EXIT; } bls::init(); for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { if (mode == tbl[i].name) { tbl[i].exec(); return 0; } } 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; }