An Elliptic Curve Cryptography is a set of asymmetric cryptography algorithms. It uses private and public keys that are related to each other and create a key pair.
For detailed API documentation of this module, see Elliptic Curve Cryptography Key Management.
A private key is known only to the owner. It cannot be shared with anyone. Leaking a private key causes serious security issues for products that use such a key. From the technical point of view, a private key is a random big integer (for example, 256-bit long) that fulfills the constraints defined by the curve parameters.
A public key can be shared with anyone. It is generated from a private key. This operation is one way, so it is computationally infeasible to compute a private key from a public key. From the technical point of view, a public key is a point on the elliptic curve over finite field, so it consists of x and y coordinates (or only one coordinate in case of Curve25519 and Ed25519). Each coordinate is a big integer with the same size as the associated private key.
A key pair is associated with a specific curve type and can be used only for the curve that it was created for. See Backends for a list of curve types supported by this library. A key pair is used for both ECDSA - Elliptic Curve Digital Signature Algorithm and ECDH - Elliptic Curve Diffie–Hellman.
In this library:
The library allows for conversion between this internal representation and raw format, which is an array of bytes containing two big integers in big-endian order or one integer in little-endian order in case of Curve25519 and Ed25519. Array types nrf_crypto_ecc_raw_private_key_t and nrf_crypto_ecc_raw_public_key_t are big enough to hold a raw key for any of the enabled curve types. There are also curve-specific types, for example nrf_crypto_ecc_secp256r1_private_key_t or nrf_crypto_ecc_secp256r1_raw_private_key_t that can be used to reduce memory consumption. See Memory saving for more details.
A public key and a private key can be generated using the nrf_crypto library. Use nrf_crypto_ecc_key_pair_generate to generate a key pair or nrf_crypto_ecc_public_key_calculate to only calculate a public key from a known private key. It is not necessary to store the private and public key pair together. A public key can be generated from a private key on demand. This reduces memory usage, but it causes slower access to public key. Use the following functions to run conversions between internal key representation and raw format:
Byte order of all the input and output byte arrays corresponds to the common practice in the ECC cryptography. Curve25519 and Ed25519 use little-endian, while the other curve types use big-endian. The function nrf_crypto_ecc_byte_order_invert can be used to convert between little-endian and big-endian. NRF_CRYPTO_CURVE25519_BIG_ENDIAN_ENABLED option can be set 1 to change the endiannes of Curve25519.
Each function that creates a new key needs a nrf_crypto_ecc_curve_info_t structure. Users should not define the content of this structure. Instead, the library defines it in global variables, such as g_nrf_crypto_ecc_secp256r1_curve_info for secp256r1.
Private-public key pair generation:
Public key generation from an existing private key:
Conversion of a raw private key to internal representation:
Conversion of internal representation of a public key to a raw public key:
Private and public keys can also be generated outside of the device using OpenSSL or other similar tools. The following two commands show how OpenSSL can be used to create a priv.pem
file with a newly generated key pair and show the content in raw hex format:
Curve name "secp256r1" can be replaced by any other curve name in the above example. OpenSSL uses different naming for brainpool curves: "brainpoolPXYZr1" instead of "bpXYZr1". The public key in OpenSSL output resulting from this command is prefixed by byte '04' and a private key may be prefixed by a zero byte '00', so they must be removed before using the key in the nrf_crypto library.
The ECC part of the cryptography library uses the following backends to provide public key cryptography:
ECC functionality depends on the selected backend. Function availability is summarized in below table:
API functions | CC310 | mbed TLS | Oberon | µECC | CC310_BL |
---|---|---|---|---|---|
nrf_crypto_ecc_key_pair_generate | | | | | |
nrf_crypto_ecc_public_key_calculate | | | | ||
nrf_crypto_ecc_private_key_from_raw | | | | | |
nrf_crypto_ecc_private_key_to_raw | | | | | |
nrf_crypto_ecc_public_key_from_raw | | | | | |
nrf_crypto_ecc_public_key_to_raw | | | | | |
nrf_crypto_ecc_private_key_free 1 nrf_crypto_ecc_public_key_free 1 | | | | | |
1 - Key-free functions are implemented only in mbed TLS backend. Other backends have empty functions to keep API compatibility.
RNG - Random Number Generator is required for the nrf_crypto_ecc_key_pair_generate function. It must be correctly configured and initialized before calling the function.
Each supported curve type can be independently selected from any of the enabled backends. This can be done using the SDK configuration header file. For example:
In this example, users can use curve secp256r1, curve secp521r1, and Curve25519 in their application. Curves secp256r1 and secp521r1 will be realized by the CC310 library and Curve25519 will be realized by the Oberon crypto library.
It is not possible to enable the same curve in two or more backends. This results in a compilation error. For more details, see Configuring nrf_crypto frontend and backends.
The first step to memory saving is to disable all curves that are not used (see Enabling the curves). This allows to remove unused code and reduces the size of some unions. Additionally, backends have different memory requirements, so choosing a different backend can help.
All ECC API (including ECDSA and ECDH) uses types that are big enough to hold data for the biggest curve. In situations in which the exact curve type is known, you can use curve-specific types. Type casting must be done to pass a curve-specific type in a parameter. There is no point in using curve-specific types when only one curve is enabled. The following example table shows types specific to curve secp256r1.
The following example demonstrates how to use curve-specific types to hold a newly generated key pair.
Backends offer different types of curves and schemes. To use a specific curve, an appropriate backend and curve inside it must be enabled. The following table summarizes backend support for different types of curves and schemes.
CC310 | mbed TLS | Oberon | µECC | CC310_BL | |
---|---|---|---|---|---|
NIST Group | |||||
secp160r1 | | ||||
secp160r2 | | ||||
secp192r1 | | | | ||
secp224r1 | | | | | |
secp256r1 | | | | | |
secp384r1 | | | |||
secp521r1 | | | |||
Koblitz Group | |||||
secp160k1 | | ||||
secp192k1 | | | |||
secp224k1 | | | |||
secp256k1 | | | | ||
Brainpool Group | |||||
bp256r1 | | ||||
bp384r1 | | ||||
bp512r1 | | ||||
Curve25519 Group | |||||
Curve25519 1 | | | | ||
Ed25519 2 | | |
1 - Curve25519 allows only ECDH. ECDSA is not possible using Curve25519.
2 - Ed25519 is a digital signature scheme only. It does not allow ECDH.
See ECDH Example and ECDSA Example for an example of how to handle the keys.