a portable and fast pairing-based cryptography library
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.
mcl/sample/bgn_smpl.cpp

126 lines
2.8 KiB

/*
sample of somewhat homomorphic encryption(SHE) by BGN with prime order group
*/
#define PUT(x) std::cout << #x << "=" << (x) << std::endl;
#include <cybozu/benchmark.hpp>
#include <mcl/bgn.hpp>
using namespace mcl::bgn;
void miniSample()
{
// init library
BGN::init();
SecretKey sec;
// init secret key by random_device
sec.setByCSPRNG();
// set range to decode GT DLP
sec.setRangeForGTDLP(1000);
PublicKey pub;
// get public key
sec.getPublicKey(pub);
const int N = 5;
int a[] = { 1, 5, -3, 4, 6 };
int b[] = { 4, 2, 1, 9, -2 };
// compute correct value
int sum = 0;
for (size_t i = 0; i < N; i++) {
sum += a[i] * b[i];
}
std::vector<CipherText> ca(N), cb(N);
// encrypt each a[] and b[]
for (size_t i = 0; i < N; i++) {
pub.enc(ca[i], a[i]);
pub.enc(cb[i], b[i]);
}
CipherText c;
c.clearAsMultiplied(); // clear as multiplied before using c.add()
// inner product of encrypted vector
for (size_t i = 0; i < N; i++) {
CipherText t;
CipherText::mul(t, ca[i], cb[i]); // t = ca[i] * cb[i]
c.add(t); // c += t
}
// decode it
int m = sec.dec(c);
// verify the value
if (m == sum) {
puts("ok");
} else {
printf("err correct %d err %d\n", sum, m);
}
}
void usePrimitiveCipherText()
{
// init library
BGN::init();
SecretKey sec;
// init secret key by random_device
sec.setByCSPRNG();
// set range to decode GT DLP
sec.setRangeForGTDLP(1000);
PublicKey pub;
// get public key
sec.getPublicKey(pub);
int a1 = 1, a2 = 2;
int b1 = 5, b2 = -4;
CipherTextG1 c1, c2; // size of CipherTextG1 = N * 2 ; N = 256-bit for CurveFp254BNb
CipherTextG2 d1, d2; // size of CipherTextG2 = N * 4
pub.enc(c1, a1);
pub.enc(c2, a2);
pub.enc(d1, b1);
pub.enc(d2, b2);
c1.add(c2); // CipherTextG1 is additive HE
d1.add(d2); // CipherTextG2 is additive HE
CipherTextM cm; // size of CipherTextM = N * 12 * 4
CipherTextM::mul(cm, c1, d1); // cm = c1 * d1
cm.add(cm); // 2cm
int m = sec.dec(cm);
int ok = (a1 + a2) * (b1 + b2) * 2;
if (m == ok) {
puts("ok");
} else {
printf("err m=%d ok=%d\n", m, ok);
}
std::string s;
s = c1.getStr(mcl::IoFixedSizeByteSeq); // serialize
printf("c1 data size %d byte\n", (int)s.size());
c2.setStr(s, mcl::IoFixedSizeByteSeq);
printf("deserialize %s\n", c1 == c2 ? "ok" : "ng");
s = d1.getStr(mcl::IoFixedSizeByteSeq); // serialize
printf("d1 data size %d byte\n", (int)s.size());
d2.setStr(s, mcl::IoFixedSizeByteSeq);
printf("deserialize %s\n", d1 == d2 ? "ok" : "ng");
s = cm.getStr(mcl::IoFixedSizeByteSeq); // serialize
printf("cm data size %d byte\n", (int)s.size());
CipherTextM cm2;
cm2.setStr(s, mcl::IoFixedSizeByteSeq);
printf("deserialize %s\n", cm == cm2 ? "ok" : "ng");
}
int main()
try
{
miniSample();
usePrimitiveCipherText();
} catch (std::exception& e) {
printf("err %s\n", e.what());
return 1;
}