const vector<unsigned char> CryptoPpDlogZpSafePrime::decodeGroupElementToByteArray(GroupElement * groupElement) { ZpSafePrimeElementCryptoPp * zp_element = dynamic_cast<ZpSafePrimeElementCryptoPp *>(groupElement); if (!(zp_element)) throw invalid_argument("element type doesn't match the group type"); //Given a group element y, find the two inverses z,-z. Take z to be the value between 1 and (p-1)/2. Return s=z-1 biginteger y = zp_element->getElementValue(); biginteger p = ((ZpGroupParams * ) groupParams)->getP(); MathAlgorithms::SquareRootResults roots = MathAlgorithms::sqrtModP_3_4(y, p); biginteger goodRoot; biginteger halfP = (p - 1) / 2; if (roots.getRoot1()>1 && roots.getRoot1() < halfP) goodRoot = roots.getRoot1(); else goodRoot = roots.getRoot2(); goodRoot -= 1; CryptoPP::Integer cpi = biginteger_to_cryptoppint(goodRoot); int len = ceil((cpi.BitCount() + 1) / 8.0); //ceil(find_log2_floor(goodRoot) / 8.0); byte * output = new byte[len]; cpi.Encode(output, len); vector<byte> res; // Remove the padding byte at the most significant position (that was added while encoding) for (int i = 1; i < len; ++i) res.push_back(output[i]); return res; }
CryptoPP::ECP::Point Mul (const CryptoPP::ECP::Point& p, const CryptoPP::Integer& e) const { CryptoPP::ECP::Point res {0, 1}; if (!e.IsZero ()) { auto bitCount = e.BitCount (); for (int i = bitCount - 1; i >= 0; i--) { res = Sum (res, res); if (e.GetBit (i)) res = Sum (res, p); } } return res; }