why i hate C

read through the code of github.com/bitcoin-core/secp256k1

find me the part where i can convert an x-only key to a standard 33 byte 257 bit EC key with sign bit

been digging at this for a few hours now

C coders don't think logically, they think bureaucratically

i would have less trouble understanding what is happening in Assembler than this shit

Reply to this note

Please Login to reply.

Discussion

The first byte is the sign. 02 or 03 for negative or positive. Then the next 32 bytes or 256 bits are the X coord.

there is two valid 33 byte keys for any given 32 byte key

when you derive ECDH you have to have the correct 33 byte key

otherwise, essentially there is two secrets that can come out of the ECDH, the odd, and the even one... the information is literally elided from the pubkey, so this means that i have to generate two secrets, one from your npub as even, one as odd, and one of them will be correct

and the only way i would be able to know that, is if there is a sentinel in the ciphertext that i can use to determine, preferably, quickly, that it's odd or even

it sorta seems to me like an ECDH protocol has to use 33 bytes, no matter what

yeah, i found the problem

when you generate keys you have to derive the pubkey and check the key is even (02) or it's not valid 32 byte BIP-340 key

i'm now needing to go check through all my stuff because generating secrets for nostr requires this, period.

yeah, woo, it's a crapshoot

i rewrote my test to see how often it failed

50% +/- 1%

so, you have to sometimes add a 0x02 to the front of BIP-340 pubkeys, and sometimes 0x03

you can only really check this if you know the secret or if you have a valid signature to try both on

ok, so hmm now what

both the ways i am thinking through this result in extra computation

so, in my code i have an ECDH generation, doing this for nip-04/nip-44 implementation

the magic is that if i put a 02 in front (even pubkey) and it fails, if i switch that for a 03 in front, and it passes, then that is correct

my measurements so far show that on average, using only the 02 fails 50% of the time, unsurprisingly, as it is literally a coinflip

so, how do i do ecdh with x-only pubkeys

there has to be a preliminary test to it, i mean, the ECDH derivation using x-only pubkeys implicitly needs to produce two possible secrets, and one will be correct if the pairs are correct

ok, i think i can deal with this, just write an ec derivation that gives back the two options, and then OR the comparisons of these with the candidate, and if true, done

ok, this is complicated though

it makes it more complicated on the decode... is there sentinels in the plaintext that i will get when i prode the ciphertext that i can positively verify and determine whether it needs to be odd or even

oh well, for testing anyway, just gonna revise the API to return the two possible secrets based on the x-only pubkey in an ecdh

i know that the secret can't be wrong, so one of the public keys will be wrong, and if both are wrong, then it fails

the question is this:

ECDH is done using a 257 bit (33 byte) pubkey, to derive a secret

if you just stick a 02 in front, then you are wrong 50% of the time when the actual pubkey is 03

i kinda mistakenly believed that BIP-340 solved this problem by just making all keys even but it seems i am wrong about that

gonna keep researching this, but the problem i'm having writing a test for ECDH is that the 32 byte key is missing the sign/oddness bit and thus deriving the correct decryption secret is a coinflip

That's not an issue I have run into with the vector tests. Maybe i need to do more research on this, I though only the positive (0x02) value was valid for nostr according to nip01. Happy to be wrong right now though.

yeah, that's what i thought!

so i've b0rked something here

no, i seriously had this understanding until today and then encounter ECDH not working correctly, i must be doing something wrong with a pubkey somewhere

If I'm not mistaken this is the basis for the twist vulnerability.

agree in some ways but they also think more like computers think, all problem in c become a mem alloc and free problem and thats cool, permit to have control over what is happening.