Skip to content

Nexa Keys

Nexa transactions are secured through the use of key-pairs generated by all senders and receivers. The key-pair is comprised of a private key, which is generated randomly and stored securely on a user's device, and a public key, which is calculated from the private key but can be sent to others without revealing the private key. The private key can be used to generate signatures, which can then be verified using the public key.

Private Key Generation

Nexa uses elliptic-curve cryptography (ECC); in particular, the secp256k1 curve with 32-byte (256-bit) private keys.

From SEC 2, ver. 2.0, the curve parameters are as follows:

The elliptic curve domain parameters over Fp associated with a Koblitz curve secp256k1 are specified by the sextuple \(T = (p, a, b, G, n, h)\) where the finite field \(F_p\) is defined by:

\[ p = FFFFFFFF\ FFFFFFFF\ FFFFFFFF\ FFFFFFFF\ FFFFFFFF\ FFFFFFFF\ FFFFFFFE\ FFFFFC2F\\ = 2^256 − 2^32 − 2^9 − 2^8 − 2^7 − 2^6 − 2^4 − 1 \]

The curve \(E\): \(y^2 = x^3 + ax + b\) over \(F_p\) is defined by:

\[ a = 00000000\ 00000000\ 00000000\ 00000000\ 00000000\ 00000000\\ 00000000\ 00000000\\ b = 00000000\ 00000000\ 00000000\ 00000000\ 00000000\ 00000000\\ 00000000\ 00000007\\ \]

The base point \(G\) in compressed form is: $$ G=02\ 79BE667E\ F9DCBBAC\ 55A06295\ CE870B07\ 029BFCDB\ 2DCE28D9\ 59F2815B\ 16F81798 $$ and in uncompressed form is: $$ G=04\ 79BE667E\ F9DCBBAC\ 55A06295\ CE870B07\ 029BFCDB\ 2DCE28D9\ 59F2815B\ 16F81798\ 483ADA77\ 26A3C465\ 5DA4FBFC\ 0E1108A8\ FD17B448\ A6855419\ 9C47D08F\ FB10D4B8 $$

Finally the order \(n\) of \(G\) and the cofactor are:

\[ n = FFFFFFFF\ FFFFFFFF\ FFFFFFFF\ FFFFFFFE\ BAAEDCE6\\ AF48A03B\ BFD25E8C\ D0364141\\ h = 01 \]

Private keys are then 256-bit values and can be chosen at random from the set \([1, n-1]\).

It is important that private keys are stored securely and never revealed to untrusted third-parties. Anyone with access to a given private key would be able to control any funds secured with that key.

Public Key Generation

Public keys are created by performing scalar multiplication of the generator, G, with the private key.

This means that public keys are a point on the elliptic curve, represented as two 256-bit coordinates, \((x, y)\). This means that a full public key is 512-bits (64 bytes) in length. However, since elliptic curves are symmetrical across the x-axis, there are always two y-values that correspond to a given x-value, which can be calculated using the curve function, \(E\). These are also necessarily negations of each other mod p (i.e. \(y_1 = p - y_2\)). As a result, public keys are often compressed into 33 bytes, 32 bytes for the x-value and an additional bit (generally expanded to a full byte) indicating which y-value should be used.

When included in scripts, public keys follow one of two formats:

Uncompressed Public Key Format

Field Length Format Description
magic number 1 byte byte Always 0x04, indicating that this is an uncompressed public key.
x-value 32 bytes bytes The zero-padded x-value of the public key.
y-value 32 bytes bytes The zero-padded y-value of the public key.

Compressed Public Key Format

Field Length Format Description
magic number 1 byte byte 0x02 if the (discarded) y-value was even, 0x03 if it was odd. This bytes indicates both that this is a compressed public key and which y-value should be used.

NOTE: this works because the y-values are negations of each other (mod p), so it is always that case that one is even and the other odd.
x-value 32 bytes bytes The zero-padded x-value of the public key.