/* tripartie Diffie-Hellman */ #include #include #include #include #include static cybozu::RandomGenerator rg; const std::string skSuf = ".sk.txt"; const std::string pkSuf = ".pk.txt"; using namespace mcl::bn256; void keygen(const std::string& user) { if (user.empty()) { throw cybozu::Exception("keygen:user is empty"); } const char *aa = "12723517038133731887338407189719511622662176727675373276651903807414909099441"; const char *ab = "4168783608814932154536427934509895782246573715297911553964171371032945126671"; const char *ba = "13891744915211034074451795021214165905772212241412891944830863846330766296736"; const char *bb = "7937318970632701341203597196594272556916396164729705624521405069090520231616"; bn256init(); G2 Q(Fp2(aa, ab), Fp2(ba, bb)); G1 P(-1, 1); Fr s; s.setRand(rg); G1::mul(P, P, s); G2::mul(Q, Q, s); { std::string name = user + skSuf; std::ofstream ofs(name.c_str(), std::ios::binary); ofs << s << std::endl; } { std::string name = user + pkSuf; std::ofstream ofs(name.c_str(), std::ios::binary); ofs << P << std::endl; ofs << Q << std::endl; } } void load(G1& P, G2& Q, const std::string& fileName) { std::ifstream ifs(fileName.c_str(), std::ios::binary); ifs >> P >> Q; } void share(const std::string& skFile, const std::string& pk1File, const std::string& pk2File) { bn256init(); Fr s; G1 P1, P2; G2 Q1, Q2; { std::ifstream ifs(skFile.c_str(), std::ios::binary); ifs >> s; } load(P1, Q1, pk1File); load(P2, Q2, pk2File); Fp12 e; BN::pairing(e, P1, Q2); { // verify(not necessary) Fp12 e2; BN::pairing(e2, P2, Q1); if (e != e2) { throw cybozu::Exception("share:bad public key file") << e << e2; } } Fp12::pow(e, e, s); std::cout << "share key:\n" << e << std::endl; } int main(int argc, char *argv[]) try { if (argc == 3 && strcmp(argv[1], "keygen") == 0) { keygen(argv[2]); } else if (argc == 5 && strcmp(argv[1], "share") == 0) { share(argv[2], argv[3], argv[4]); } else { fprintf(stderr, "tri-dh.exe keygen \n"); fprintf(stderr, "tri-dh.exe share \n"); return 1; } } catch (std::exception& e) { printf("ERR %s\n", e.what()); return 1; }