I understand how ringCTs work and know that they require a key image of the private key of the input that is actually being spent. How is this created? Couldn’t you just hash the private key of the real input?
An output has public key
P and private key
P = xG and
G is the well-known ed25519 base point.
The key image is
Hp() is a function that takes a hash of
P and returns a valid curve point.
Couldn’t you just hash the private key of the real input?
Take a look at the section 3.4 Back’s Linkable Spontaneous Anonymous Group (bLSAG) signatures in Zero-to-Monero
That is the simplest example of a linkable ring signature, and all of Monero's more complex ring signatures are essentially based on this concept.
For the key image to be verified, even the simple bLSAG scheme requires the key image to be the scalar multiplication of the private key
x on a point other than
G. In simple (non-Monero) situations, that alternate point could be e.g. another universally well-known point
H. However, if Monero used
H instead of
Hp(P), it would be possible for someone that sends you outputs to detect if you've later spent more than one of them (see Notes on the hash function Hp on page 17 of the CryptoNote white paper).