<blockquote>
  <p>I was told that the minimum number is 0.</p>
</blockquote>

<p>That is correct. <code>0x3400000000000000000000000000000000000000000000000000000000000000</code> is a valid x-coordinate on secp256k1.</p>

<blockquote>
  <p>My understanding is that the answer is supposed to be like this: '0434' + hex(n) + y_value. I am not sure how to approach this</p>
</blockquote>

<p>That is also correct. However, you will have two y-coordinates. One even and one odd and hence two uncompressed public keys. That is the reason why we append a prefix to the x-coordinate to tell us whether the y-coordinate associated with that x-coordinate is even or odd. </p>

<blockquote>
  <p>Is it true that x-coordinate is supposed to be 32 bytes and y coordinate 32 bytes too?</p>
</blockquote>

<p>That is the maximum size. It can be below that as well.</p>

<blockquote>
  <p>Is it true that each coordinate is represented in hex mode of 64 chars?</p>
</blockquote>

<p>Related to to above. One byte representation needs two hexadecimal characters.</p>

<blockquote>
  <p>Python code</p>
</blockquote>

<p>I'll use the below one.</p>



<pre><code>p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
def modular_sqrt(n, p):
    ''' Find a quadratic residue (mod p) of 'n'. For Bitcoin p is an odd prime, that satisfies
        the identity p % 4 == 3. As a result, this is a simple solution where the modular square
        root of y^2 is : y = pow(y^2, (p + 1) // 4, p).
        If p did not satisfy that identity we would have had to use the Tonelli-Shank's algorithm
    '''
    return pow(n, (p + 1) // 4, p)

def y_coordinate_from_x(x_coordinate_with_prefix):
    public_key_x_coordinate = int(x_coordinate_with_prefix[2:], 16)
    public_key_y_coordinate_sign = int(x_coordinate_with_prefix[:2])
    y_squared = (public_key_x_coordinate**3 + 7) % int(p)
    public_key_y_coordinate = modular_sqrt(y_squared, int(p))

    # check the sign (odd or even) and match that to the sign provided by x-coordinate
    sign_check = 0 if public_key_y_coordinate_sign == 2 else 1
    if int(str(public_key_y_coordinate)[-1:]) % 2 != sign_check:
        public_key_y_coordinate = int(p) - public_key_y_coordinate

    return '%064x'%public_key_y_coordinate

x = '3400000000000000000000000000000000000000000000000000000000000000'
y1 = y_coordinate_from_x('02' + x)
y2 = y_coordinate_from_x('03' + x)
</code></pre>

<p>so your uncompressed public keys are <code>'04'+x+y1</code> and <code>'04'+x+y2</code></p>

CC BY-SA 4.0
2019-07-24T20:08:02.180Z
Thank you very much for your reply! Your code produces the same keys as mine though. And if x can be less than 32 bytes then is x=0x320 a valid point on the curve? I tried that too but it is not still the correct answer.
Δήμητρα Γεωργίου
CC BY-SA 4.0
2019-07-25T05:15:43.090Z
@ΔήμητραΓεωργίου Yes, x can be less than 32 bytes. However, not all points are members of the secp256k1 curve. For example, 0x32 is not a valid x-coordinate but 0x320 is. In most programs (including the one I pasted above), you will need to pad the public key hexadecimal to 32 bytes. Also what do you mean by correct answer?
Ugam Kamat
CC BY-SA 4.0
2019-07-25T06:19:47.247Z
Thank you again! My professor does not accept '0434000000000000000000000000000000000000000000000000000000000000009d143cafb07ae7ea8025f44c9cf201dc34e4cc71003869b81cca00e0844d16f4' or '04340000000000000000000000000000000000000000000000000000000000000062ebc3504f8518157fda0bb3630dfe23cb1b338effc79647e335ff1e7bb2e53b' as correct answers. Maybe this is what you say now: "pad the public key hexadecimal to 32 bytes".  Could you please explain what you mean?  I have really lost my mind over this.
Δήμητρα Γεωργίου
CC BY-SA 4.0
2019-07-25T06:28:51.370Z
@ΔήμητραΓεωργίου Hey, so both the keys that you mentioned are valid points on the secp256k1 curve and as such are valid Bitcoin public keys. disregard the padding, it was related to something else that might just confuse you.
Ugam Kamat
CC BY-SA 4.0
2019-07-25T06:33:28.947Z
Ok! Do you you know what is the answer to the above problem because I still don't know. Thank you again!
Δήμητρα Γεωργίου
CC BY-SA 4.0
2019-07-25T06:36:55.160Z
@ΔήμητραΓεωργίου you gotta ask your professor why he doesn't accept it (I wouldn't know about his thought process). The public keys you mentioned are valid Bitcoin public keys. May be he/she is looking for compressed public keys (the ones with just the x-coordinate and the sign of the y-coordinate as prefix)?
Ugam Kamat
CC BY-SA 4.0
2019-07-24T14:22:58.517Z
2019-07-24T16:08:40.423Z
2019-07-24T16:08:40.423Z
Ugam Kamat
<p>I am trying to create a public key whose x starts with "34" and is followed by the minimum number <strong><em>n</em></strong> such that the concatenation of "34" and <strong><em>n</em></strong> is the x of a valid point (x, y) on the elliptic curve secp256k1. Submit the concatenation of 04, x and y in hexadecimal form. This is a valid bitcoin public key, the corresponding secret key of which is not known by anyone.</p>

<p>I was told that the minimum number is 0.</p>

<p>My understanding is that the answer is supposed to be like this: <strong>'0434' + hex(n) + y_value</strong>.
I am not sure how to approach this. </p>

<p>Is it true that x-coordinate is supposed to be 32 bytes and y coordinate 32 bytes too? </p>

<p>Is it true that each coordinate is represented in hex mode of 64 chars?</p>

<p>Is the public key represented by 130 hex chars?
I have tried some online tools: e.g. <a href="https://iancoleman.io/bitcoin-key-compression/" rel="nofollow noreferrer">https://iancoleman.io/bitcoin-key-compression/</a> and some python code but I always get a wrong answer.</p>

<pre><code>X = '0x3400000000000000000000000000000000000000000000000000000000000000'
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
print("x coordinate = %s " % X)
x = int(X,16)
print(x)
ysquared = ((x*x*x+7) % p)
print("ysquared= %s " % ysquared)
y = pow(ysquared, (p+1)//4, p)
print("y1 = %s " % hex(y))
print("y2 = %s " % hex((y * -1 % p)))
print("-----------------")
print('04' + X[2:] + hex(y)[2:])
print('04' + X[2:] + hex((y * -1 % p))[2:])
</code></pre>

<public-key><ecdsa>
Creating a nothing-up-my-sleeve public key
Δήμητρα Γεωργίου
# Creating a nothing-up-my-sleeve public key

(Asked by: username_0 on 2019-07-24)

I am trying to create a public key whose x starts with "34" and is followed by the minimum number ***n*** such that the concatenation of "34" and ***n*** is the x of a valid point (x, y) on the elliptic curve secp256k1. Submit the concatenation of 04, x and y in hexadecimal form. This is a valid bitcoin public key, the corresponding secret key of which is not known by anyone.

I was told that the minimum number is 0.

My understanding is that the answer is supposed to be like this: **'0434' + hex(n) + y\_value**.
I am not sure how to approach this.

Is it true that x-coordinate is supposed to be 32 bytes and y coordinate 32 bytes too?

Is it true that each coordinate is represented in hex mode of 64 chars?

Is the public key represented by 130 hex chars?
I have tried some online tools: e.g. <https://iancoleman.io/bitcoin-key-compression/> and some python code but I always get a wrong answer.

```
X = '0x3400000000000000000000000000000000000000000000000000000000000000'
p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
print("x coordinate = %s " % X)
x = int(X,16)
print(x)
ysquared = ((x*x*x+7) % p)
print("ysquared= %s " % ysquared)
y = pow(ysquared, (p+1)//4, p)
print("y1 = %s " % hex(y))
print("y2 = %s " % hex((y * -1 % p)))
print("-----------------")
print('04' + X[2:] + hex(y)[2:])
print('04' + X[2:] + hex((y * -1 % p))[2:])

```

**Tags:** public-key, ecdsa


---

## 1 answers

### Answer by username_1 on 2019-07-24. Score: 1 | Accepted answer

> I was told that the minimum number is 0.

That is correct. `0x3400000000000000000000000000000000000000000000000000000000000000` is a valid x-coordinate on secp256k1.

> My understanding is that the answer is supposed to be like this: '0434' + hex(n) + y\_value. I am not sure how to approach this

That is also correct. However, you will have two y-coordinates. One even and one odd and hence two uncompressed public keys. That is the reason why we append a prefix to the x-coordinate to tell us whether the y-coordinate associated with that x-coordinate is even or odd.

> Is it true that x-coordinate is supposed to be 32 bytes and y coordinate 32 bytes too?

That is the maximum size. It can be below that as well.

> Is it true that each coordinate is represented in hex mode of 64 chars?

Related to to above. One byte representation needs two hexadecimal characters.

> Python code

I'll use the below one.

```
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
def modular_sqrt(n, p):
    ''' Find a quadratic residue (mod p) of 'n'. For Bitcoin p is an odd prime, that satisfies
        the identity p % 4 == 3. As a result, this is a simple solution where the modular square
        root of y^2 is : y = pow(y^2, (p + 1) // 4, p).
        If p did not satisfy that identity we would have had to use the Tonelli-Shank's algorithm
    '''
    return pow(n, (p + 1) // 4, p)

def y_coordinate_from_x(x_coordinate_with_prefix):
    public_key_x_coordinate = int(x_coordinate_with_prefix[2:], 16)
    public_key_y_coordinate_sign = int(x_coordinate_with_prefix[:2])
    y_squared = (public_key_x_coordinate**3 + 7) % int(p)
    public_key_y_coordinate = modular_sqrt(y_squared, int(p))

    # check the sign (odd or even) and match that to the sign provided by x-coordinate
    sign_check = 0 if public_key_y_coordinate_sign == 2 else 1
    if int(str(public_key_y_coordinate)[-1:]) % 2 != sign_check:
        public_key_y_coordinate = int(p) - public_key_y_coordinate

    return '%064x'%public_key_y_coordinate

x = '3400000000000000000000000000000000000000000000000000000000000000'
y1 = y_coordinate_from_x('02' + x)
y2 = y_coordinate_from_x('03' + x)

```

so your uncompressed public keys are `'04'+x+y1` and `'04'+x+y2`

> **Comments:**
> **username_0**: Thank you very much for your reply! Your code produces the same keys as mine though. And if x can be less than 32 bytes then is x=0x320 a valid point on the curve? I tried that too but it is not still the correct answer.  
> **username_1**: @username_0 Yes, x can be less than 32 bytes. However, not all points are members of the secp256k1 curve. For example, 0x32 is not a valid x-coordinate but 0x320 is. In most programs (including the one I pasted above), you will need to pad the public key hexadecimal to 32 bytes. Also what do you mean by correct answer?  
> **username_0**: Thank you again! My professor does not accept '0434000000000000000000000000000000000000000000000000000000000000009d143cafb07ae7ea8025f44c9cf201dc34e4cc71003869b81cca00e0844d16f4' or '04340000000000000000000000000000000000000000000000000000000000000062ebc3504f8518157fda0bb3630dfe23cb1b338effc79647e335ff1e7bb2e53b' as correct answers. Maybe this is what you say now: "pad the public key hexadecimal to 32 bytes".  Could you please explain what you mean?  I have really lost my mind over this.  
> **username_1**: @username_0 Hey, so both the keys that you mentioned are valid points on the secp256k1 curve and as such are valid Bitcoin public keys. disregard the padding, it was related to something else that might just confuse you.  
> **username_0**: Ok! Do you you know what is the answer to the above problem because I still don't know. Thank you again!  
> **username_1**: @username_0 you gotta ask your professor why he doesn't accept it (I wouldn't know about his thought process). The public keys you mentioned are valid Bitcoin public keys. May be he/she is looking for compressed public keys (the ones with just the x-coordinate and the sign of the y-coordinate as prefix)?  

---

