Here is a quick breakdown of how it works or how I think it works

MakeNewKey calls OpenSSL’s
EC_KEY_generate_key function to generate a new private-public key pair for the secp256k1 curve.
void MakeNewKey()
{
if (!EC_KEY_generate_key(pkey))
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
}
It then steps inside the EC_KEY_Generate from OpenSSL it then generates a random number between 1 and the order of SECP256k1 this number is the private key.
It then multiples the curve base point (G) which is a fixed point on the secp256k1 curve. the output will be points X,Y on the curve which is the public key.
Both the private key stored as a scalar and the public key as a point are in the pkey object.
CKey()
{
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
if (pkey == NULL)
throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
}
It then Initializes a new EC_KEY object with the 256k1 curve in NID_secp256k1 in OpenSSL
CPrivKey GetPrivKey() const
{
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
CPrivKey vchPrivKey(nSize, 0);
unsigned char* pbegin = &vchPrivKey[0];
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
return vchPrivKey;
}
It then converts the private key to DER format with i2d_ECPrivateKey and returns it as CPrivKey wich is a vector of bytes with a secure allocator. Typical size being 279 bytes and incluses metadata and the 32 byte private key.
vector<unsigned char> GetPubKey() const
{
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
vector<unsigned char> vchPubKey(nSize, 0);
unsigned char* pbegin = &vchPubKey[0];
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
return vchPubKey;
}
GetPubKey converts the key to byte vector using the i2o_ECPubKey format would be uncompressed 65 bytes and start with 0x04 and followed by the 32 byte X and the 32 byte Y coordinates
Other things to look at might be CBigNum which is a wrapper around OpenSSLs BIGNUM it's not used in key generation but is used in other cryptographic op's
BigNum handles large integers (keys, hashes, ect)
Provides a mehtod to convert between formats hex, binary and uint256.
Use for signing and verification ie manipulation of the hash in Sign and Verify.
1. Make a key
CKey key;
key.MakeNewKey();
2. Get PK
CPrivKey privKey = key.GetPrivKey(); // 279 bytes
3. Generate Pub Key
vector<unsigned char> pubKey = key.GetPubKey(); // 65 bytes
4. Hash pubKey to create the address.
5. User privKey to sign the TX.
You might want to poke over the early source code since bitcoin early codebase is not that extensive not too hard to pull it apart.
Can I ask why your looking for these things? seems interesting!
Good luck.