<p>You're correct that the first byte should be <code>0x03</code> if the y-coordinate of the public key is odd. So indeed, the tutorial is not correct. If the y-coordinate is odd, just set this instead:</p>
<pre><code>pubBytes[0] = 3;
</code></pre>
<p>It is worth noting, though, that you can simply negate the private key to achieve an even y-coordinate. This is obvious because if <code>[s]G = Y</code> then <code>[-s]G = -Y</code>. So it isn't really an issue if you did make this mistake and then wanted to fix it later. This was used in <a href="https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki" rel="nofollow noreferrer">BIP-340</a> to make all public keys 32-bytes instead of 33, by omitting the <code>0x02</code>/<code>0x03</code> and always assuming the even y-coordinate.</p>

CC BY-SA 4.0
2021-12-17T07:07:37.923Z
thank you for this confirmation
I have adapted my code like this ```pubBytes[0] = pt.getAffineY().mod(new BigInteger("2")).equals(BigInteger.ZERO) ? (byte) 2 : (byte) 3;```
Purple Gang
CC BY-SA 4.0
2021-12-15T00:47:59.643Z
2021-12-15T00:47:59.643Z
meshcollider
<p>I've followed <a href="https://metamug.com/article/security/java-generate-bitcoin-wallet-address.html" rel="nofollow noreferrer">this</a> tutorial on generating a Public Private key pair value and generating a valid Bitcoin address.<br>
But one part makes me wonder if the implementation is done correctly which is the following:</p>
<pre><code>ECPublicKey epub = (ECPublicKey) publicKey;
ECPoint pt = epub.getW();
byte[] pubBytes = new byte[33]; //32 + 1
pubBytes[0] = 2; //0x02
System.arraycopy(pt.getAffineX().toByteArray(), 0, pubBytes, 1, 32);
</code></pre>
<p>To me it seems like hardcoding the 0x02 could lead to errors when the last byte of the Y coordinate is odd or am I wrong?</p>
<p>If this implementation does prove to be wrong, how could I implement it correctly?</p>

CC BY-SA 4.0
2021-12-15T09:07:39.920Z
In addition to that bug, Java `BigInteger.toByteArray()` slightly more than half the time won't be 32 bytes as needed here. That looks like a good website to stay very far away from.
dave_thompson_085
CC BY-SA 4.0
2021-12-17T07:07:06.053Z
@dave_thompson_085 I have checked that and for me, ```toByteArray()``` has consistently returned 32 bytes.
Purple Gang
<address><public-key><address-generation><java>
Can I always set the first byte to 0x02 with the following implementation?
Purple Gang
# Can I always set the first byte to 0x02 with the following implementation?

(Asked by: username_0 on 2021-12-14)

I've followed [this](https://metamug.com/article/security/java-generate-bitcoin-wallet-address.html) tutorial on generating a Public Private key pair value and generating a valid Bitcoin address.  
But one part makes me wonder if the implementation is done correctly which is the following:

```
ECPublicKey epub = (ECPublicKey) publicKey;
ECPoint pt = epub.getW();
byte[] pubBytes = new byte[33]; //32 + 1
pubBytes[0] = 2; //0x02
System.arraycopy(pt.getAffineX().toByteArray(), 0, pubBytes, 1, 32);

```

To me it seems like hardcoding the 0x02 could lead to errors when the last byte of the Y coordinate is odd or am I wrong?

If this implementation does prove to be wrong, how could I implement it correctly?

**Tags:** address, public-key, address-generation, java

> **Comments:**
> **username_1**: In addition to that bug, Java `BigInteger.toByteArray()` slightly more than half the time won't be 32 bytes as needed here. That looks like a good website to stay very far away from.  
> **username_0**: @username_1 I have checked that and for me, ```toByteArray()``` has consistently returned 32 bytes.  

---

## 1 answers

### Answer by username_2 on 2021-12-15. Score: 3 | Accepted answer

You're correct that the first byte should be `0x03` if the y-coordinate of the public key is odd. So indeed, the tutorial is not correct. If the y-coordinate is odd, just set this instead:

```
pubBytes[0] = 3;

```

It is worth noting, though, that you can simply negate the private key to achieve an even y-coordinate. This is obvious because if `[s]G = Y` then `[-s]G = -Y`. So it isn't really an issue if you did make this mistake and then wanted to fix it later. This was used in [BIP-340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) to make all public keys 32-bytes instead of 33, by omitting the `0x02`/`0x03` and always assuming the even y-coordinate.

> **Comments:**
> **username_0**: thank you for this confirmation I have adapted my code like this ```pubBytes[0] = pt.getAffineY().mod(new BigInteger("2")).equals(BigInteger.ZERO) ? (byte) 2 : (byte) 3;```  

---

