pull down to refresh
0 sats \ 2 replies \ @l0k18 1 Jul 2023 \ on: A Dive Into the Math Behind Bitcoin Schnorr Signatures bitcoin
I have been working with ECDSA, specifically secp256k1 curve, and I considered using schnorr signatures in my protocol, where currently signing is used only for proving ownership of a relay identity.
It is using compact 65 byte signatures as used in bitcoin for pre-musig2 stuff, the nice thing about them is the key is embedded in them so you take the message hash, combine with the signature, and out comes the public key.
The messages all have the public key in the message, so in theory I could switch over to schnorr signature, but for saving a singular byte of space in the message it's not worth it.
I actually could remove the 33 byte public key at the head of the messages, since it can be derived out of the signature and the hash of the message, but that sorta voids the point of it. These messages amount to a 4 signature cost to dispatch a complete set of peer advertisment messages, that don't need to be redone more than once a day most of the time.
I don't think there is any other purpose for signatures in the Indra protocol at this point, and changing my code, with the substantial difference in API by the fact the signature is fed the public key from the message instead of it being derived and checked to match the public key.
But for any case of a cryptographic ledger like the bitcoin token ledger, anyone who is still designing new protocols that use ECDSA is just being silly. The time to complete IBD would be at least half, if not a quarter of the time if the signatures were all schnorr, it is that much faster, at least.
I initially envisioned more use for the signatures, and was going to use schnorr signatures, but I decided that the security from the ECDH was enough to prove controlling the receiving key for a given connection. This saved 32 bytes from all of the messages between peers so I ditched signatures on packets and messages. You can't derive the shared secret using ECDH unless you have the expected private key for which they designate the public key in the message header.
It would be great if all bitcoin signatures used them, and then, a step further, if there was coinjoin protocols that allowed non-trusted counterparties to join in a coinjoin without any counterparty risk, chain analysis would be dead. Is there one signer, two, or what? Whose are these outputs???? hahaha!
oh yeah, btw, I borrowed a bit of the schnorr signature protocol to create a rolling fast private key generator, it uses two private keys, the base and the secondary key, which is scalar multiplied with the base to derive a new base for the next message key. The private keys used by senders with the public key of the receiver are changed for every single message, since the private key is not needed to decode it, the receiver's private key can do it.
I think I probably should run this scheme past someone a bit more experienced with EC signature/secret. It's simpler but at the same time more intensive than signal (double ratchet) protocol. And yes, the receiving keys are changed routinely, they change according to a count of the bytes encrypted using it, it's concurrent and unilateral, the receiver just sends a new pubkey to use, and keeps the old one a little while in case of things getting stuck in the pipes for a few minutes.
the nice thing about them is the key is embedded in them so you take the message hash, combine with the signature, and out comes the public key
You can also do that with Schnorr! (although not with Key-Prefixed Schnorr, which is used in Bitcoin)
In Bitcoin,
e = H(R || D || m)
, but if you are free to design the protocol you could just as easily make this e = H(R || m)
like with canonical Schnorr signatures.If
e = H(R || m)
, you can compute e
without knowing the pubkey in advance. Then you can recover the public key which created the signature like so.s = r + e*d s*G = R + e*D e*D = s*G - R D = (s*G - R) / e
(Dividing by
e
is the same as multiplying by the multiplicative inverse of e
)oh yeah, btw, I borrowed a bit of the schnorr signature protocol to create a rolling fast private key generator, it uses two private keys, the base and the secondary key, which is scalar multiplied with the base to derive a new base for the next message key. The private keys used by senders with the public key of the receiver are changed for every single message, since the private key is not needed to decode it, the receiver's private key can do it.
Interesting, what's the purpose of such a scheme?
reply
So that recoverable pubkey can be hiding in the 64 bytes? ok I need to look at this because of the reduction in computation complexity.
The cloak is to make it impossible for anyone without the correct private key to acquire the ECDH secret of a message. They only have one half, the public key of the sender, which is a different key derived via scalar addition for each packet (and message, or onion, if you prefer).
The packet dispatch between peers is of uniform sized packets and in any given stream there can be millions of different looking cloaks (2^24) and the key changes are done far more frequently than this. Traffic between peers is a mass of these identical looking messages that you can't separate without knowing secrets.
The messages that are broken up into the packets also have these keys in the onion layers of encryption, again each one has a new secret key giving a different public key each time.
Really just obeying the rules of how to use EC. Never the same hash to be signed twice. Easy to guarantee it with a random 8 byte nonce in every message.
reply