<div dir="ltr">A public key on an elliptic curve is formally defined by an X and a Y coordinate. However, given only the X coordinate and the curve parameters, the value of Y squared can be calculated, which leaves only two candidates for the actual value of Y. So many systems support 'compressions' of EC points to save space: they express a public key as an X coordinate plus a flag to indicate which of the two possible Y values to use.<div><div><br></div><div>The Erlang crypto library returns the public key in uncompressed format, which is indicated by the 0x04 byte. If point compression were applied, the value would be 0x02 or 0x03 (the flag to indicate which Y coordinate to select) plus a 256 bit X coordinate.</div><div><br></div><div>TL;DR: yes, for interoperability with tools that use raw uncompressed EC points, the leading 0x04 can be dropped.</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 10 Jul 2020 at 17:38, <a href="mailto:ludovic@demblans.com">ludovic@demblans.com</a> <<a href="mailto:ludovic@demblans.com">ludovic@demblans.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Hello,<br>
<br>
I am trying some crypto code, mostly for fun. I want to generate an Ethereum public key from a know private key.<br>
<br>
This is a sample private key : <<22,99,59,58,153,154,229,99,217,142,170,105,82,105,204,11,55,249,101,152,109,41,109,195,18,134,228,189,83,139,28,92>><br>
<br>
I run this code:<br>
<br>
    -module(t).<br>
    -export([run/0]).<br>
<br>
    run() -> <br>
        PrivateKey = <<22,99,59,58,153,154,229,99,217,142,170,105,82,105,204,11,55,249,101,152,109,41,109,195,18,134,228,189,83,139,28,92>>,<br>
        {PublicKey, NewPrivateKey} = crypto:generate_key(ecdh, secp256k1, PrivateKey),<br>
        dump_hex("Private key", PrivateKey),<br>
        dump_hex("Public key", PublicKey).<br>
<br>
    dump_hex(Label, Bin) -> <br>
        io:format("~s: ~s~n", [Label, [io_lib:format("~2.16.0B",[X]) || <<X:8>> <= Bin]]).<br>
<br>
And I get this result:<br>
<br>
    Private key: 16633B3A999AE563D98EAA695269CC0B37F965986D296DC31286E4BD538B1C5C<br>
    Public key: 047D5ED8E5B1843FF0EF0F443419E3DC589D900F3C683D2D7268AC1D9FE47F7E7350A1...(cut)<br>
 <br>
But I am expected to find this: 7D5ED8E5B1843FF0EF0F443419E3DC589D900F3C683D2D7268AC1D9FE47F7E7350A...(cut)<br>
<br>
At first I was quite discouraged because crypto is hard to learn, but after giving a closer look I found that I have the correct key actually. I just have an extra leading byte. The expected length is 512 bits and I have 520.<br>
<br>
Expected   7D5ED8E5B1843FF0EF0F443419E3DC589D900F3C683D...(cut)<br>
Mine     047D5ED8E5B1843FF0EF0F443419E3DC589D900F3C683D...(cut)<br>
<br>
Do you know why the crypto library behaves like this ? Can I just cut the extra leading byte ? <br>
<br>
Thank you<br>
<br>
- lud<br>
<br>
</blockquote></div>