PointGFp OS2ECP(const byte data[], size_t data_len, const CurveGFp& curve) { if(data_len <= 1) return PointGFp(curve); // return zero const byte pc = data[0]; BigInt x, y; if(pc == 2 || pc == 3) { //compressed form x = BigInt::decode(&data[1], data_len - 1); const bool y_mod_2 = ((pc & 0x01) == 1); y = decompress_point(y_mod_2, x, curve); } else if(pc == 4) { const size_t l = (data_len - 1) / 2; // uncompressed form x = BigInt::decode(&data[1], l); y = BigInt::decode(&data[l+1], l); } else if(pc == 6 || pc == 7) { const size_t l = (data_len - 1) / 2; // hybrid form x = BigInt::decode(&data[1], l); y = BigInt::decode(&data[l+1], l); const bool y_mod_2 = ((pc & 0x01) == 1); if(decompress_point(y_mod_2, x, curve) != y) throw Illegal_Point("OS2ECP: Decoding error in hybrid format"); } else throw Invalid_Argument("OS2ECP: Unknown format type"); PointGFp result(curve, x, y); if(!result.on_the_curve()) throw Illegal_Point("OS2ECP: Decoded point was not on the curve"); return result; }
std::pair<BigInt, BigInt> OS2ECP(const uint8_t data[], size_t data_len, const BigInt& curve_p, const BigInt& curve_a, const BigInt& curve_b) { if(data_len <= 1) throw Decoding_Error("OS2ECP invalid point"); const uint8_t pc = data[0]; BigInt x, y; if(pc == 2 || pc == 3) { //compressed form x = BigInt::decode(&data[1], data_len - 1); const bool y_mod_2 = ((pc & 0x01) == 1); y = decompress_point(y_mod_2, x, curve_p, curve_a, curve_b); } else if(pc == 4) { const size_t l = (data_len - 1) / 2; // uncompressed form x = BigInt::decode(&data[1], l); y = BigInt::decode(&data[l+1], l); } else if(pc == 6 || pc == 7) { const size_t l = (data_len - 1) / 2; // hybrid form x = BigInt::decode(&data[1], l); y = BigInt::decode(&data[l+1], l); const bool y_mod_2 = ((pc & 0x01) == 1); if(decompress_point(y_mod_2, x, curve_p, curve_a, curve_b) != y) throw Illegal_Point("OS2ECP: Decoding error in hybrid format"); } else throw Invalid_Argument("OS2ECP: Unknown format type " + std::to_string(pc)); return std::make_pair(x, y); }