<p>These are used in the "hybrid" public key format, which is an uncompressed format (it has both X and Y coordinates, like 0x04) that still stores the odd/evenness of the Y coordinate (like 0x02/0x03).</p>

<p>It is defined in ANSI X9.62-1998 Sections 4.3.6 and 4.3.7, and seems totally useless to me. However, OpenSSL supported it, thus when switching to libsecp256k1 for validation, it had to support it too, or we'd risk consensus failures in the network if such a pubkey would ever be used. Now we're pretty much stuck with it.</p>

CC BY-SA 3.0
2017-08-10T08:38:51.680Z
2017-08-10T08:38:51.680Z
Pieter Wuille
<p>In the <code>eckey_impl.h</code> header file, the implementation of <code>secp256k1_eckey_pubkey_parse</code> checks if the first byte of a 65-byte public key is <code>0x04</code>, <code>0x06</code> or <code>0x07</code>. Where can I find documentation regarding the <code>0x06</code> and <code>0x07</code> prefixes?</p>

<pre><code>static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) {
    if (size == 33 &amp;&amp; (pub[0] == 0x02 || pub[0] == 0x03)) {
        secp256k1_fe x;
        return secp256k1_fe_set_b32(&amp;x, pub+1) &amp;&amp; secp256k1_ge_set_xo_var(elem, &amp;x, pub[0] == 0x03);
    } else if (size == 65 &amp;&amp; (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
        secp256k1_fe x, y;
        if (!secp256k1_fe_set_b32(&amp;x, pub+1) || !secp256k1_fe_set_b32(&amp;y, pub+33)) {
            return 0;
        }
        secp256k1_ge_set_xy(elem, &amp;x, &amp;y);
        if ((pub[0] == 0x06 || pub[0] == 0x07) &amp;&amp; secp256k1_fe_is_odd(&amp;y) != (pub[0] == 0x07)) {
            return 0;
        }
        return secp256k1_ge_is_valid_var(elem);
    } else {
        return 0;
    }
}
</code></pre>

<public-key><secp256k1>
C secp256k1: What do prefixes 0x06 and 0x07 in an uncompressed public key signify?
sarva
# C secp256k1: What do prefixes 0x06 and 0x07 in an uncompressed public key signify?

(Asked by: username_0 on 2017-08-10)

In the eckey_impl.h header file, the implementation of secp256k1_eckey_pubkey_parse checks if the first byte of a 65-byte public key is 0x04, 0x06 or 0x07. Where can I find documentation regarding the 0x06 and 0x07 prefixes?
static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) {
    if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
        secp256k1_fe x;
        return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
    } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
        secp256k1_fe x, y;
        if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
            return 0;
        }
        secp256k1_ge_set_xy(elem, &x, &y);
        if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07)) {
            return 0;
        }
        return secp256k1_ge_is_valid_var(elem);
    } else {
        return 0;
    }
}

**Tags:** public-key, secp256k1


---

## 1 answers

### Answer by username_1 on 2017-08-10. Score: 5 | Accepted answer

These are used in the "hybrid" public key format, which is an uncompressed format (it has both X and Y coordinates, like 0x04) that still stores the odd/evenness of the Y coordinate (like 0x02/0x03).

It is defined in ANSI X9.62-1998 Sections 4.3.6 and 4.3.7, and seems totally useless to me. However, OpenSSL supported it, thus when switching to libsecp256k1 for validation, it had to support it too, or we'd risk consensus failures in the network if such a pubkey would ever be used. Now we're pretty much stuck with it.


---

