/* * ECDH implemenation * (C) 2007 Manuel Hartl, FlexSecure GmbH * 2007 Falko Strenzke, FlexSecure GmbH * 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ #include namespace Botan { ECDH_KA_Operation::ECDH_KA_Operation(const ECDH_PrivateKey& key) { cofactor = key.domain().get_cofactor(); curve = key.domain().get_curve(); l_times_priv = inverse_mod(cofactor, key.domain().get_order()) * key.private_value(); } SecureVector ECDH_KA_Operation::agree(const byte w[], u32bit w_len) const { PointGFp point = OS2ECP(w, w_len, curve); PointGFp S = (cofactor * point) * l_times_priv; S.check_invariants(); return BigInt::encode_1363(S.get_affine_x(), curve.get_p().bytes()); } /** * Derive a key */ SecureVector ECDH_PrivateKey::derive_key(const byte key[], u32bit key_len) const { PointGFp point = OS2ECP(key, key_len, public_point().get_curve()); return derive_key(point); } /** * Derive a key */ SecureVector ECDH_PrivateKey::derive_key(const ECDH_PublicKey& key) const { return derive_key(key.public_point()); } /** * Derive a key */ SecureVector ECDH_PrivateKey::derive_key(const PointGFp& point) const { const BigInt& cofactor = domain().get_cofactor(); const BigInt& n = domain().get_order(); BigInt l = inverse_mod(cofactor, n); // can precompute this PointGFp S = (cofactor * point) * (private_value() * l); S.check_invariants(); return BigInt::encode_1363(S.get_affine_x(), point.get_curve().get_p().bytes()); } }