FBB::ECDH(3bobcat)
π FBB::ECDH π β from the 3bobcat manual, bestie
okay so. you're here because you're doing Elliptic Curve Diffie-Hellman and you want shared keys, and honestly? valid. let's get into it. no cap, this one's a whole journey, so grab a snack π
β¨ NAME β¨
FBB::ECDH β Elliptic Curve Diffie-Hellman PKI, computing shared keys π
β¨ SYNOPSIS β¨
#include <bobcat/ecdh>
Linking option: -lbobcat -lcrypto
that's it, that's the vibe check. you include the header, you link against -lbobcat and -lcrypto, periodt π«Ά
β¨ DESCRIPTION β¨
So the class FBB::ECDH computes shared keys (aka shared secrets) by applying elliptic keys to the Diffie-Hellman (1976) algorithm. Yes, 1976, it's vintage and it ate π
The Diffie-Hellman algorithm uses public and private information and it gives you a public key infrastructure (PKI). The public info is literally just an elliptic curve specification plus a public key β and you can share that over insecure media, bestie, it's built different. π₯
The Diffie-Hellman algorithm is commonly used to compute a shared key, and that shared key then gets used to encrypt info sent between two parties.
So here's the tea. One party β called the initiator in this man-page β does this at construction time:
- specifies an elliptic curve π
- constructs a public and private key
- writes the public key in hexadecimal big-endian form, followed by the name of the used elliptic curve, to file π
The initiator's private key gets written to file separately, because the private key is required for computing the shared key. Also, encryption may be used when writing the private key to file. π
Next the initiator passes the file with the initiator's public key and the name of the used elliptic curve to the other party, called the peer in this man-page.
The peer, having received the initiator's (public key) file, constructs an FBB::ECDH object. The peer's ECDH constructor:
- computes the peer's public and private key π
- writes the peer's public key to file
- constructs the shared key π
Once the peer's ECDH object has been constructed, the peer can write the shared key to file. The peer's private key may optionally also be written to file, but that's optional, because the peer's private key is not required for subsequent computations. Encryption may also be used when writing the peer's private key to file.
The file containing the peer's public key is then sent to the initiator. The initiator constructs an ECDH object specifying the names of:
- the used elliptic curve
- the file containing the initiator's private key
- the file containing the peer's public key
Once this ECDH object has been constructed the peer may write the shared key to file.
The initiator and peer's shared keys are identical and can be used for symmetric encryption of sensitive info shared between the initiator and the peer. iconic, honestly. π
FBB::Exceptions are thrown if the ECDH constructors or members cannot complete their tasks. (so catch them, bestie π)
π¦ Perfect Forward Secrecy and Ephemeral Diffie Hellman π¦
The initiator and peer may decide not to save their private information once they've constructed their shared keys β which gives you Perfect Forward Secrecy and Ephemeral Diffie Hellman. Here, this procedure is applied like this:
- Initiator and peer have agreed upon and securely exchanged a long-lasting common secret, which may be used in combination with, e.g., symmetric encryption methods.
- Applying the procedure described in the previous section, the private keys are not saved on files, and the process constructing the initiator's ECDH object may not terminate, but must remain active until the peer's public key has been received. Once the initiator's process has constructed the public key that key is encrypted using the common secret, and is then sent to the peer. Alternatively, the initiator's private key may temporarily be stored in shared memory or may temporarily be stored encrypted on file.
- The peer, having received the initiator's public key, constructs the shared secret, encrypts the peer's public key, and sends the encrypted public key to the initiator.
- The initiator upon receipt of the peer's public key, computes the shared key, either by continuing the temporarily suspended construction process or by retrieving the shared key from memory or file, removing the storage (memory or file) thereafter.
- Since the private keys and the public keys are not stored or kept on files the shared keys cannot be reconstructed, while a Man-In-The-Middle attack is prevented by only exchanging encrypted public information. π‘οΈ
- The shared key can now be used to encrypt a communication session
πΈ Document encryption using Diffie Hellman πΈ
As with PKI in general, the Diffie Hellman key exchange method itself is normally not used for encrypting documents. Instead, it's used to obtain a key that's used for symmetric encryption methods like 3DES or CBC. These symmetric encryption methods are available through, e.g., Bobcats' ISymCryptStream and OSymCryptStream classes. π«
β¨ NAMESPACE β¨
FBB
All constructors, members, operators and manipulators mentioned in this man-page are defined in the namespace FBB. π«Ά
β¨ INHERITS FROM β¨
-
(nothing, bestie, it stands on its own π)
β¨ ENUMERATIONS β¨
The class ECDH defines two enumerations, each having one defined value. The enumerations are used to select specific overloaded versions of the ECDH constructors or set members:
- The
t(enum TheInitiator)has valueInitiatorand is used to select overloaded versions meant for the initiator; - The
t(enum ThePeer)has valuePeerand is used to select overloaded versions meant for the peer.
β¨ CONSTRUCTORS β¨
ECDH()β The default constructor is available merely constructing a valid object. It also prepares a map of all elliptic curves predefined by openSSL. As all other constructors use default constructor delegation the map is also available after calling the other constructors; πΊοΈECDH(TheInitiator init, std::string const &curveName, std::string const &initPubFname)β This constructor initializes the ECDH object to be used by the initiator, constructing the initiator's private and public keys using the elliptic curve specified bycurveName(e.g.,secp384r1, see alsooperator<<below). The initiator's public key (in big-endian hexadecimal format) andcurveNameare written toinitPubFname;
This constructor should be called by the initiator to start the Diffie-Hellman shared key computation procedure; π
ECDH(ThePeer peer, std::string const &initPubFname, std::string const &peerPubFname)β This constructor is used by the peer, having received the initiator's public info on the fileinitPubFname. It constructs the peer's private and public keys as well as the shared key. The peer's public key (in big-endian hexadecimal format) is written topeerPubFname, which file is then be sent to the initiator; πECDH(std::string const &curveName, std::string const &peerPubFname, std::string const &initSecFname, std::string const passphrase = "")β Once the initiator has received the peer's public key (in the filepeerPubFname) this constructor constructs the initiator's version of the shared key. Here, the initiator has previously saved the initiator's private key toinitSecFname, optionally using encryption. If encryption was used then the then usedpassphrasemust also be specified when using this constructor. π
The move constructor (and move assignment operator) is available. π§
π MEMBER FUNCTIONS π
okay bestie, here's where the actual magic happens. every single one of these, no skips, no cap:
std::string const &curve() constβ hands you back the elliptic curve that's being used, that's it, that's the function. πstd::string privKey() constβ returns the private key, all big-endian and hex-formatted, and it comes prefixed by a line containinghex. β¨void privKey(std::string const &privKeyFname, std::string passphrase) constβ encrypts the private key with the AES-256-GCM encryption algorithm, usingpassphraseas the passphrase. then it gets written toprivKeyFname, prefixed by a line containingencrypted. important:passphrasehas to be at least five characters and it can totally contain multiple words. π«Άstd::string const &pubKey() constβ gives you the public key as a big-endian hexadecimal string. iconic. π₯void set(TheInitiator init, std::string const &curveName, std::string const &initPubFname)β this is the one the initiator calls, building the initiator's private and public keys using the elliptic curve named bycurveName. the initiator's public key (big-endian hexadecimal format, obvi) pluscurveNameget written toinitPubFname. it's automatically called by the constructor that takes the same parameters, but you can also call it explicitly later if you used the default constructor. πvoid set(ThePeer peer, std::string const &initPubFname, std::string const &peerPubFname)β the peer's turn, and this one assumes the peer already got the initiator's public info from the fileinitPubFname. it constructs the peer's private and public keys and the shared key. the peer's public key (big-endian hexadecimal format again, we stay consistent) goes topeerPubFname, and that file then gets sent to the initiator. also automatically called by the constructor with the same parameters, and also callable explicitly after using the default constructor. π€void set(std::string const &curveName, std::string const &peerPubFname, std::string const &initSecFname, std::string const passphrase = "")β initiator's version of things, called once the peer's public key (that's the filepeerPubFname) has arrived. it computes the initiator's shared key. when you use this member, the initiator previously saved its private key toinitSecFname, optionally with encryption. if encryption was used, you must pass that passphrase as the last argument. don't forget it, bestie. πstd::string const &sharedKey() constβ returns the computed shared key, big-endian hexadecimal format. done and dusted. πΈstd::string const &sharedKey(std::string const &peerPubFname)β plot twist: instead of using theset(std::string const &curveName, ...)member or theECDH(std::string const &curveName, ...)constructor, the initiator can just call theset(TheInitiator init, ...)member or theECDH(TheInitiator init, ...)constructor, and let the process it's running in suspend until the file with the peer's public key shows up. then this member gets called on the constructedECDHobject to grab the initiator's shared key. the glow-up here? the initiator doesn't have to save the initiator's private key at all. main character efficiency. π
π OVERLOADED OPERATOR π
std::ostream &operator<<(ostream &out, ECDH const &ecdh)β writes the currently available elliptic curves and their associated comment toout. alphabetically ordered, one elliptic curve per line. cute and tidy. β¨
π EXAMPLE π
start the program with one of the following arguments:
curves: show the available elliptic curves oncout;init: compute the initiator's public/secret keys, writing them toinit.pubandinit.sec;peer: compute the peer's public/secret keys, writing them topeer.pubandpeer.sec, and compute the peer's shared key (peer.shared);priv: compute the initiator's shared key (init.shared) after makingpeer.pubavailable in a separate process, using a single initiator process.shared: compute the initiator's shared key (init.shared) using a separate initiator process.
and here's the whole thing, verbatim, because girlies don't paraphrase code:
#include "main.ih"
int main(int argc, char **argv)
try
{
if (argc == 1)
{
usage(path{ argv[0] }.filename().string());
return 0;
}
if ("curves"s == argv[1]) // show supported ECDH curves.
cout << ECDH{};
else if ("init"s == argv[1]) // initiator key construction
{
// write the file containing
// the curve + public key
ECDH ecdh{ ECDH::Initiator, "secp384r1", "init.pub" };
// save the initiatorβs
// private key
ecdh.privKey("init.sec", "use your passphrase");
// not using encryption:
// auto initSec = Exception::factory<ofstream>("init.sec");
// initSec << ecdh.privKey() << β\nβ;
}
else if ("priv"s == argv[1]) // initiator key construction
{
// write the file containing
// the curve + public key
ECDH ecdh{ ECDH::Initiator, "secp384r1", "init.pub" };
cout << "wait for the peerβs public key. "
"Press Enter to continue... ";
cin.ignore(100, β\nβ);
// written to file
auto initShared = Exception::factory<ofstream>("init.shared");
initShared << ecdh.sharedKey("peer.pub") << β\nβ;
}
else if ("peer"s == argv[1]) // peerβs key construction
{
// write the peerβs public key
ECDH ecdh{ ECDH::Peer, "init.pub", "peer.pub" };
// save the peerβs private
// key (although not needed)
auto out = Exception::factory<ofstream>("peer.sec");
out << ecdh.privKey() << β\nβ;
out = Exception::factory<ofstream>("peer.shared");
out << ecdh.sharedKey() << β\nβ;
}
else if ("shared"s == argv[1]) // the initiatorβs shared key
{ // construction
ECDH ecdh{ "secp384r1", "peer.pub", "init.sec",
"use your passphrase" };
auto initShared = Exception::factory<ofstream>("init.shared");
initShared << ecdh.sharedKey() << β\nβ; // written to file
}
else
{
usage(path{ argv[0] }.filename().string());
return 1;
}
}
catch (exception const &exc)
{
cerr << "Error: " << exc.what() << β\nβ;
return 1;
}
catch (...) // and handle an unexpected exception
{
cerr << "unexpected exception\n";
return 1;
}
π¦ FILES π¦
bobcat/ecdhβ defines the class interface
β SEE ALSO β
bobcat(7), bigint(3bobcat), diffiehellman(3bobcat), isymcryptstream(3bobcat), osymcryptstream(3bobcat)
go read those too, iykyk π
π BUGS π
None Reported.
(genuinely no notes. flawless behavior. we love to see it.) β¨
π BOBCAT PROJECT FILES π
- https://fbb-git.gitlab.io/bobcat/: gitlab project page;
Debian Bobcat project files:
libbobcat6: debian package containing the shared library, changelog and copyright note;libbobcat-dev: debian package containing the static library, headers, manual pages, and developer info;
πΈ BOBCAT πΈ
Bobcat is an acronym of Brokkenβs Own Base Classes And Templates. yes bestie, it's a backronym situation, we stan. π
π§ COPYRIGHT π§
This is free software, distributed under the terms of the GNU General Public License (GPL).
π AUTHOR π
Frank B. Brokken (f.b.brokken@rug.nl).
and that's the whole page, bestie!! this one's from libbobcat-dev_6.15.01, dated 2005-2026, page FBB::ECDH(3bobcat) β go forth and elliptic-curve your little heart out π«Άπ
β¨
π¦ where this page comes from
- ubuntu stonking: libbobcat-dev 6.15.01-1 Β· GPL-3.0-or-later WITH OpenSSL exception
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms