herumi / mcl

a portable and fast pairing-based cryptography library
BSD 3-Clause "New" or "Revised" License
452 stars 152 forks source link

question about serialize performance #46

Closed huyuguang closed 5 years ago

huyuguang commented 5 years ago

I am using the curve bn254. I found the performance of the mcl::EcT<Fp2>::load() is weird slow.

In my computer, load 1M(1024768) G2 from a data file using 450 seconds (single thread). It seems that the main cost is the function getYfromX() which need to compute the Square Root of the Y.

Since the data file is generated by myself, how can I save the G2 with the Y? I know, in this case, the data file size will *2. Maybe I should not use the mcl::IoMode::IoSerialize, which flag should I use? I do not understand all those flags.

My code looks like:

typedef mcl::EcT<Fp2> G2;
struct imembuf : public std::streambuf {
  imembuf(char const* array, size_t len) {
    char* p(const_cast<char*>(array));
        this->setg(p, p, p + len);
  }
};

struct imemstream : virtual imembuf, std::istream {
  imemstream(char* array, size_t len)
      : imembuf(array, len), std::istream(static_cast<std::streambuf*>(this)) {}
};

bool BinToG2(uint8_t const* buf, G2* g) {
  bool ret;
  imemstream in((char*)buf, 64);
  g->load(&ret, in, mcl::IoMode::IoSerialize);
  return ret;
}
herumi commented 5 years ago

Are you already disable the checking the order of points in G2? https://github.com/herumi/mcl#verify-an-element-in-g2

herumi commented 5 years ago

how can I save the G2 with the Y? I know, in this case, the data file size will *2.

If there is no infinity, then

const size_t Fp2BufSize = 64; // for BN254
const size_t G2BufSize = Fp2BufSize * 2;

bool G2ToBin(uint8_t *buf, const G2 *g)
{
  assert(g->isNormalized());
  size_t n = g->x.serialize(buf, Fp2BufSize);
  if (n == 0) return false;
  n = g->y.serialize(buf + Fp2BufSize, Fp2BufSize);
  return n > 0;
}

bool BinToG2(uint8_t const *buf, G2 *g)
{
  g->z = 1;
  size_t n = g->x.deserialize(buf, G2BufSize);
  if (n == 0) return false;
  n = g->y.deserialize(buf + Fp2BufSize, G2BufSize);
  return n > 0;
}