You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
2.5 KiB
110 lines
2.5 KiB
/*
|
|
tripartie Diffie-Hellman
|
|
*/
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <cybozu/random_generator.hpp>
|
|
#include <mcl/bn.hpp>
|
|
#include <cybozu/option.hpp>
|
|
|
|
typedef mcl::FpT<mcl::FpTag, 256> Fp;
|
|
typedef mcl::bn::BNT<Fp> BN;
|
|
typedef BN::Fp2 Fp2;
|
|
typedef BN::Fp12 Fp12;
|
|
typedef BN::G1 G1;
|
|
typedef BN::G2 G2;
|
|
|
|
struct FrTag;
|
|
typedef mcl::FpT<FrTag, 256> Fr;
|
|
|
|
static cybozu::RandomGenerator rg;
|
|
|
|
const std::string skSuf = ".sk.txt";
|
|
const std::string pkSuf = ".pk.txt";
|
|
|
|
void setup()
|
|
{
|
|
BN::init();
|
|
Fr::init(BN::param.r);
|
|
}
|
|
|
|
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";
|
|
|
|
setup();
|
|
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)
|
|
{
|
|
setup();
|
|
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, Q2, P1);
|
|
{
|
|
// verify(not necessary)
|
|
Fp12 e2;
|
|
BN::pairing(e2, Q1, P2);
|
|
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 <user name>\n");
|
|
fprintf(stderr, "tri-dh.exe share <secret key file> <public key1 file> <public key2 file>\n");
|
|
return 1;
|
|
}
|
|
} catch (std::exception& e) {
|
|
printf("ERR %s\n", e.what());
|
|
return 1;
|
|
}
|
|
|
|
|