bool PointGFp::operator==(const PointGFp& other) const { if(m_curve != other.m_curve) return false; // If this is zero, only equal if other is also zero if(is_zero()) return other.is_zero(); return (get_affine_x() == other.get_affine_x() && get_affine_y() == other.get_affine_y()); }
// encoding and decoding secure_vector<uint8_t> EC2OSP(const PointGFp& point, uint8_t format) { if(point.is_zero()) return secure_vector<uint8_t>(1); // single 0 byte const size_t p_bytes = point.get_curve().get_p().bytes(); BigInt x = point.get_affine_x(); BigInt y = point.get_affine_y(); secure_vector<uint8_t> bX = BigInt::encode_1363(x, p_bytes); secure_vector<uint8_t> bY = BigInt::encode_1363(y, p_bytes); if(format == PointGFp::UNCOMPRESSED) { secure_vector<uint8_t> result; result.push_back(0x04); result += bX; result += bY; return result; } else if(format == PointGFp::COMPRESSED) { secure_vector<uint8_t> result; result.push_back(0x02 | static_cast<uint8_t>(y.get_bit(0))); result += bX; return result; } else if(format == PointGFp::HYBRID) { secure_vector<uint8_t> result; result.push_back(0x06 | static_cast<uint8_t>(y.get_bit(0))); result += bX; result += bY; return result; } else throw Invalid_Argument("EC2OSP illegal point encoding"); }
bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, const byte sig[], size_t sig_len) { if(sig_len != order.bytes()*2) return false; BigInt e(msg, msg_len); BigInt r(sig, sig_len / 2); BigInt s(sig + sig_len / 2, sig_len / 2); if(r <= 0 || r >= order || s <= 0 || s >= order) return false; BigInt w = inverse_mod(s, order); PointGFp R = w * multi_exponentiate(base_point, e, public_point, r); if(R.is_zero()) return false; return (R.get_affine_x() % order == r); }
// Point addition void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) { if(is_zero()) { m_coord_x = rhs.m_coord_x; m_coord_y = rhs.m_coord_y; m_coord_z = rhs.m_coord_z; return; } else if(rhs.is_zero()) return; const BigInt& p = m_curve.get_p(); const size_t cap_size = 2*m_curve.get_p_words() + 2; for(size_t i = 0; i != ws_bn.size(); ++i) ws_bn[i].ensure_capacity(cap_size); BigInt& rhs_z2 = ws_bn[0]; BigInt& U1 = ws_bn[1]; BigInt& S1 = ws_bn[2]; BigInt& lhs_z2 = ws_bn[3]; BigInt& U2 = ws_bn[4]; BigInt& S2 = ws_bn[5]; BigInt& H = ws_bn[6]; BigInt& r = ws_bn[7]; BigInt& tmp = ws_bn[9]; secure_vector<word>& monty_ws = ws_bn[8].get_word_vector(); /* https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2 */ m_curve.sqr(rhs_z2, rhs.m_coord_z, monty_ws); m_curve.mul(U1, m_coord_x, rhs_z2, monty_ws); m_curve.mul(tmp, rhs.m_coord_z, rhs_z2, monty_ws); // z^3 m_curve.mul(S1, m_coord_y, tmp, monty_ws); m_curve.sqr(lhs_z2, m_coord_z, monty_ws); m_curve.mul(U2, rhs.m_coord_x, lhs_z2, monty_ws); m_curve.mul(tmp, m_coord_z, lhs_z2, monty_ws); m_curve.mul(S2, rhs.m_coord_y, tmp, monty_ws); H = U2; H -= U1; if(H.is_negative()) H += p; r = S2; r -= S1; if(r.is_negative()) r += p; if(H.is_zero()) { if(r.is_zero()) { mult2(ws_bn); return; } // setting to zero: m_coord_x = 0; m_coord_y = 1; m_coord_z = 0; return; } m_curve.sqr(U2, H, monty_ws); m_curve.mul(S2, U2, H, monty_ws); m_curve.mul(tmp, U1, U2, monty_ws); U2 = tmp; m_curve.sqr(m_coord_x, r, monty_ws); m_coord_x -= S2; m_coord_x -= (U2 << 1); while(m_coord_x.is_negative()) m_coord_x += p; U2 -= m_coord_x; if(U2.is_negative()) U2 += p; m_curve.mul(m_coord_y, r, U2, monty_ws); m_curve.mul(tmp, S1, S2, monty_ws); m_coord_y -= tmp; if(m_coord_y.is_negative()) m_coord_y += p; m_curve.mul(tmp, m_coord_z, rhs.m_coord_z, monty_ws); m_curve.mul(m_coord_z, tmp, H, monty_ws); }
// Point addition void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) { if(is_zero()) { coord_x = rhs.coord_x; coord_y = rhs.coord_y; coord_z = rhs.coord_z; return; } else if(rhs.is_zero()) return; const BigInt& p = curve.get_p(); BigInt& rhs_z2 = ws_bn[0]; BigInt& U1 = ws_bn[1]; BigInt& S1 = ws_bn[2]; BigInt& lhs_z2 = ws_bn[3]; BigInt& U2 = ws_bn[4]; BigInt& S2 = ws_bn[5]; BigInt& H = ws_bn[6]; BigInt& r = ws_bn[7]; monty_sqr(rhs_z2, rhs.coord_z); monty_mult(U1, coord_x, rhs_z2); monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2)); monty_sqr(lhs_z2, coord_z); monty_mult(U2, rhs.coord_x, lhs_z2); monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2)); H = U2; H -= U1; if(H.is_negative()) H += p; r = S2; r -= S1; if(r.is_negative()) r += p; if(H.is_zero()) { if(r.is_zero()) { mult2(ws_bn); return; } *this = PointGFp(curve); // setting myself to zero return; } monty_sqr(U2, H); monty_mult(S2, U2, H); U2 = monty_mult(U1, U2); monty_sqr(coord_x, r); coord_x -= S2; coord_x -= (U2 << 1); while(coord_x.is_negative()) coord_x += p; U2 -= coord_x; if(U2.is_negative()) U2 += p; monty_mult(coord_y, r, U2); coord_y -= monty_mult(S1, S2); if(coord_y.is_negative()) coord_y += p; monty_mult(coord_z, monty_mult(coord_z, rhs.coord_z), H); }
// Point addition void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) { if(is_zero()) { m_coord_x = rhs.m_coord_x; m_coord_y = rhs.m_coord_y; m_coord_z = rhs.m_coord_z; return; } else if(rhs.is_zero()) return; const BigInt& p = m_curve.get_p(); BigInt& rhs_z2 = ws_bn[0]; BigInt& U1 = ws_bn[1]; BigInt& S1 = ws_bn[2]; BigInt& lhs_z2 = ws_bn[3]; BigInt& U2 = ws_bn[4]; BigInt& S2 = ws_bn[5]; BigInt& H = ws_bn[6]; BigInt& r = ws_bn[7]; /* http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-1998-cmo-2 */ curve_sqr(rhs_z2, rhs.m_coord_z); curve_mult(U1, m_coord_x, rhs_z2); curve_mult(S1, m_coord_y, curve_mult(rhs.m_coord_z, rhs_z2)); curve_sqr(lhs_z2, m_coord_z); curve_mult(U2, rhs.m_coord_x, lhs_z2); curve_mult(S2, rhs.m_coord_y, curve_mult(m_coord_z, lhs_z2)); H = U2; H -= U1; if(H.is_negative()) H += p; r = S2; r -= S1; if(r.is_negative()) r += p; if(H.is_zero()) { if(r.is_zero()) { mult2(ws_bn); return; } // setting to zero: m_coord_x = 0; m_coord_y = 1; m_coord_z = 0; return; } curve_sqr(U2, H); curve_mult(S2, U2, H); U2 = curve_mult(U1, U2); curve_sqr(m_coord_x, r); m_coord_x -= S2; m_coord_x -= (U2 << 1); while(m_coord_x.is_negative()) m_coord_x += p; U2 -= m_coord_x; if(U2.is_negative()) U2 += p; curve_mult(m_coord_y, r, U2); m_coord_y -= curve_mult(S1, S2); if(m_coord_y.is_negative()) m_coord_y += p; curve_mult(m_coord_z, curve_mult(m_coord_z, rhs.m_coord_z), H); }