pw_crypto#

Stable

A set of safe (read: easy to use, hard to misuse) crypto APIs.

The following crypto services are provided by this module.

  1. Hashing a message with SHA256.

  2. Verifying a digital signature signed with ECDSA over the NIST P256 curve.

  3. Many more to come …

SHA256#

  1. Obtaining a oneshot digest.

#include "pw_crypto/sha256.h"

std::byte digest[32];
if (!pw::crypto::sha256::Hash(message, digest).ok()) {
  // Handle errors.
}

// The content can also come from a pw::stream::Reader.
if (!pw::crypto::sha256::Hash(reader, digest).ok()) {
  // Handle errors.
}
  1. Hashing a long, potentially non-contiguous message.

#include "pw_crypto/sha256.h"

std::byte digest[32];

if (!pw::crypto::sha256::Sha256()
         .Update(chunk1)
         .Update(chunk2)
         .Update(chunk...)
         .Final()
         .ok()) {
  // Handle errors.
}

ECDSA#

  1. Verifying a digital signature signed with ECDSA over the NIST P256 curve.

#include "pw_crypto/sha256.h"

std::byte digest[32];
if (!pw::crypto::sha256::Hash(message, digest).ok()) {
  // handle errors.
}

if (!pw::crypto::ecdsa::VerifyP256Signature(public_key, digest, signature)
         .ok()) {
  // handle errors.
}
  1. Verifying a digital signature signed with ECDSA over the NIST P256 curve, with a long and/or non-contiguous message.

#include "pw_crypto/sha256.h"

std::byte digest[32];

if (!pw::crypto::sha256::Sha256()
         .Update(chunk1)
         .Update(chunk2)
         .Update(chunkN)
         .Final(digest)
         .ok()) {
  // Handle errors.
}

if (!pw::crypto::ecdsa::VerifyP256Signature(public_key, digest, signature)
         .ok()) {
  // Handle errors.
}

AES#

  1. Computing the AES-CMAC of a potentially long and/or non-contiguous message. This is similar to a hash or digest except that the operation takes a secret key as an input, so the MAC can be used to verify integrity and authentication.

#include "pw_crypto/aes.h"

std::byte mac[16];

if (!pw::crypto::aes_cmac::Cmac(key)
         .Update(chunk1)
         .Update(chunk2)
         .Update(chunk...)
         .Final()
         .ok()) {
  // Handle errors.
}
  1. Encrypting a single AES 128-bit block.

Warning

This is a low-level operation. Users should know exactly what they are doing and must ensure that this operation does not violate any safety bounds that more refined operations usually ensure.

#include "pw_crypto/aes.h"

std::byte encrypted[16];

if (!pw::crypto::unsafe::aes::EncryptBlock(key, message, encrypted).ok()) {
  // Handle errors.
}

ECDH#

  1. Generating a keypair and computing a shared symmetric key.

Warning

Ensure that the backend is initialized and configured correctly with a cryptographically secure pseudo-random number generator (CSPRNG). The details for doing this are specific to each backend.

#include "pw_crypto/ecdh.h"

// Import the public key from the other party.
PW_TRY_ASSIGN(auto public_key,
              pw::crypto::ecdh::P256PublicKey::Import(other_x,
                                                      other_y,
                                                      endian));
PW_TRY_ASSIGN(auto keypair, pw::crypto::ecdh::P256Keypair::Generate());

std::byte shared_key[32];
if (!keypair.ComputeDiffieHellman(public_key, shared_key)) {
  // handle errors.
}
  1. Import a pre-existing keypair (for testing purposes) and computing a shared symmetric key.

#include "pw_crypto/ecdh.h"

// Import the public key from the other party.
PW_TRY_ASSIGN(auto public_key,
              pw::crypto::ecdh::P256PublicKey::Import(other_x,
                                                      other_y,
                                                      endian));
PW_TRY_ASSIGN(
    auto keypair,
    pw::crypto::ecdh::P256Keypair::ImportForTesting(private_key, x, y, endian));

std::byte shared_key[32];
if (!keypair.ComputeDiffieHellman(public_key, shared_key)) {
  // handle errors.
}

Configuration#

The crypto services offered by pw_crypto can be backed by different backend crypto libraries.

MbedTLS#

The MbedTLS project is a mature and full-featured crypto library that implements cryptographic primitives, X.509 certificate manipulation and the SSL/TLS and DTLS protocols.

The project also has good support for interfacing to cryptographic accelerators.

The small code footprint makes the project suitable and popular for embedded systems.

Enabling the MbedTLS Backend#

To select the MbedTLS backend, the MbedTLS library needs to be installed and configured.

GN#
# Install and configure MbedTLS
pw package install mbedtls
gn gen out --args='
    dir_pw_third_party_mbedtls=getenv("PW_PACKAGE_ROOT")+"/mbedtls"
    pw_crypto_SHA256_BACKEND="//pw_crypto:sha256_mbedtls_v3"
    pw_crypto_ECDSA_BACKEND="//pw_crypto:ecdsa_mbedtls_v3"
    pw_crypto_AES_BACKEND="//pw_crypto:aes_mbedtls_v3"
    pw_crypto_ECDH_BACKEND="//pw_crypto:ecdh_mbedtls_v3"
'

ninja -C out
Bazel#

If using Bazel, add a bazel_dep on MbedTLS to your MODULE.bazel file and select appropriate backends by adding them to your project’s platform:

platform(
  name = "my_platform",
  flags = [
     "@pigweed//pw_crypto:sha256_backend=@pigweed//pw_crypto:sha256_mbedtls",
     "@pigweed//pw_crypto:ecdsa_backend=@pigweed//pw_crypto:ecdsa_mbedtls",
     "@pigweed//pw_crypto:aes_backend=@pigweed//pw_crypto:aes_mbedtls",
     "@pigweed//pw_crypto:ecdh_backend=@pigweed//pw_crypto:ecdh_mbedtls",
     # ... other flags
   ],
)

Configuring MbedTLS#

MbedTLS is configured via setting compile-time flags in a config.h header. These flags are enumerated in the MbedTLS docs.

By default, Pigweed provides a default MbedTLS configuration for both MCU and host targets. However, projects making use of MbedTLS should strongly consider providing their own config.

Bazel#

The config file is set via the mbedtls//:mbedtls_config label flag.

  1. Create your config.h based on Pigweed’s default config in third_party/mbedtls/config_pigweed.h, or MbedTLS’s example configs.

  2. In your BUILD.bazel, define a library for your header:

cc_library(
    name = "mbedtls_config",
    hdrs = [
        "my_config/my_mbedtls_config.h",
    ],
    strip_include_prefix = "my_config",
    tags = ["noclangtidy"],
    defines = [
        "MBEDTLS_CONFIG_FILE='\"my_mbedtls_config.h\"'",
    ]
)
  1. Set the label flag in your project’s platform or .bazelrc:

...
"@@mbedtls+//:mbedtls_config": "@mymodule//crypto:mbedtls_config",
...

Hardware Acceleration#

MbedTLS supports linking against alternative implementations for many modules, such as entropy, AES, and SHA-2. These ALT functions are typically used to provide hardware-accelerated cryptography engines.

Bazel#
  1. Build your implementation against MbedTLS headers:

cc_library(
    name = "sha256_alt",
    hdrs = [ "sha256_alt.h" ],
    deps = [
        "@pigweed//targets:mcuxpresso_sdk",
    ]
)

cc_library(
    name = "mbedtls_sha256_hashcrypt",
    srcs = [
        "mbedtls_sha256_hashcrypt.cc",
    ],
    deps = [
        ":sha256_alt",
        "@mbedtls",
        "@pigweed//targets:mcuxpresso_sdk",
    ]
)
  1. Modify your MbedTLS config.h:

...
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA256_ALT
    ...
  1. Set platform label flags:

...
"@@mbedtls+//:mbedtls_config": "@mymodule//crypto:mbedtls_config",
"@pigweed//pw_crypto:sha256_backend": "@pigweed//pw_crypto:sha256_mbedtls",
"@pigweed//pw_crypto:mbedtls_sha256_engine": "@mymodule//crypto:mbedtls_sha256_hashcrypt",
...

Configuration Tips#

For optimal code size and/or performance, the MbedTLS library can be configured per product. MbedTLS configuration is achieved by turning on and off MBEDTLS_* options in a config.h file. See //third_party/mbedtls for how this is done.

pw::crypto::sha256 does not need any special configuration as it uses the mbedtls_sha256_* APIs directly. However you can optionally turn on MBEDTLS_SHA256_SMALLER to further reduce the code size to from 3KiB to ~1.8KiB at a ~30% slowdown cost (Cortex-M4).

#define MBEDTLS_SHA256_SMALLER

pw::crypto::ecdsa requires the following minimum configurations which yields a code size of ~12KiB.

#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ECDSA_C
// The ASN1 options are needed only because mbedtls considers and verifies
// them (in check_config.h) as dependencies of MBEDTLS_ECDSA_C.
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ECP_NO_INTERNAL_RNG
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED

If using pw::crypto::ecdh, a CSPRNG must be set to provide cryptographically-secure randomness when generating keypairs. To do this, provide an instance of pw::crypto::ecdh::backend::Csprng to pw::crypto::ecdh::backend::SetCsprng(). MbedTLS MUST have been configured with an entropy pool that has collected sufficient (>128 bits estimated) entropy with one or more calls to

mbed_entropy_add_source(&entropy, ...)

Then the following implementation can be used to provide a CTR DRBG as the CSPRNG for ECDH:

using MbedtlsCtrDrbg =
    ::pw::crypto::ecdh::backend::Wrapper<mbedtls_ctr_drbg_context,
                                         mbedtls_ctr_drbg_init,
                                         mbedtls_ctr_drbg_free>;
class MbedtlsCsprng final : public ::pw::crypto::ecdh::backend::Csprng {
 public:
  MbedtlsCsprng(mbedtls_entropy_context* entropy,
                std::string_view personalization_string) {
    PW_CHECK_INT_EQ(0,
                    mbedtls_ctr_drbg_seed(ctr_drbg_.Get(),
                                          mbedtls_entropy_func,
                                          &entropy,
                                          personalization_string.data(),
                                          personalization_string.size()));
  }

  GenerateResult Generate(ByteSpan out) override {
    if (mbedtls_ctr_drbg_random(ctr_drbg_.Get(),
                                reinterpret_cast<unsigned char*>(out.data()),
                                out.size()) != 0) {
      return GenerateResult::kFailure;
    }
    return GenerateResult::kSuccess;
  }

 private:
  MbedtlsCtrDrbg ctr_drbg_;
};

BoringSSL#

The BoringSSL project (source, GitHub mirror) is a fork of OpenSSL maintained by Google. It is not especially designed to be embedded-friendly, but it is used as the SSL library in Chrome, Android, and other apps. It is likely better to use another backend such as Mbed-TLS for embedded targets unless your project needs BoringSSL specifically.

To use the BoringSSL backend with a GN project, it needs to be installed and configured. To do that:

# Install and configure BoringSSL
pw package install boringssl
gn gen out --args='
    dir_pw_third_party_boringssl=getenv("PW_PACKAGE_ROOT")+"/boringssl"
    pw_crypto_AES_BACKEND="//pw_crypto:aes_boringssl"
    pw_crypto_ECDH_BACKEND="//pw_crypto:ecdh_boringssl"
'

ninja -C out

If using Bazel, add the BoringSSL repository to your MODULE.bazel and select appropriate backends by adding them to your project’s platform:

platform(
  name = "my_platform",
  constraint_values = [
    "@pigweed//pw_aes:aes_boringssl_backend",
    # ... other constraint_values
  ],
)

Size Reports#

Below are size reports for each crypto service. These vary across configurations.

Label

Segment

Delta

SHA256

FLASH

+16

[section .rodata]

+4

__bi_84

+20

main

NEW

+2,308

mbedtls_internal_sha256_process

NEW

+256

K

NEW

+238

mbedtls_sha256_finish

NEW

+150

mbedtls_sha256_update

NEW

+104

pw::crypto::sha256::Sha256::Final()

NEW

+88

mbedtls_sha256_starts

NEW

+64

pw::crypto::sha256::Sha256::Update()

NEW

+44

pw::crypto::sha256::Sha256::Sha256()

NEW

+40

pw::crypto::sha256::Hash()

NEW

+28

mbedtls_platform_zeroize

NEW

+24

pw::crypto::sha256::backend::DoInit()

NEW

+20

pw::crypto::sha256::backend::DoUpdate()

NEW

+16

pw::crypto::sha256::backend::DoFinal()

NEW

+14

mbedtls_sha256_free

NEW

+10

mbedtls_sha256_init

NEW

+4

memset_func

+3,448

ECDSA P256 Verify

FLASH

+164

[section .rodata]

-8

vClearInterruptMaskFromISR

+4

__bi_84

+32

main

+2

fit::internal::null_target_move()

NEW

+1,844

ecp_mul_restartable_internal

NEW

+1,264

mbedtls_ecp_group_load

NEW

+936

ecp_mod_p384

NEW

+830

ecp_mod_p256

NEW

+800

mbedtls_mpi_div_mpi

NEW

+768

brainpoolP384r1_T

NEW

+768

brainpoolP512r1_T

NEW

+768

secp384r1_T

NEW

+768

secp521r1_T

NEW

+592

mbedtls_mpi_inv_mod

NEW

+528

ecp_double_jac

NEW

+500

ecp_add_mixed

NEW

+454

ecp_mod_p224

NEW

+436

mbedtls_mpi_exp_mod

NEW

+420

mbedtls_ecp_point_read_binary

NEW

+408

ecp_normalize_jac_many

NEW

+384

brainpoolP256r1_T

NEW

+384

secp192k1_T

NEW

+384

secp192r1_T

NEW

+384

secp224k1_T

NEW

+384

secp224r1_T

NEW

+384

secp256k1_T

NEW

+384

secp256r1_T

NEW

+360

mbedtls_mpi_core_mla

NEW

+358

mbedtls_mpi_core_exp_mod

NEW

+352

mbedtls_ecp_check_pubkey

NEW

+328

mbedtls_ecdsa_verify_restartable

NEW

+230

mbedtls_mpi_gcd

NEW

+224

ecp_mod_koblitz

NEW

+220

mbedtls_mpi_mul_mpi

NEW

+204

ecp_mod_p448

NEW

+200

mbedtls_ecp_mul_shortcuts

NEW

+192

pw::crypto::ecdsa::VerifyP256Signature()

NEW

+180

mbedtls_mpi_mul_mod

NEW

+172

ecp_mod_p192

NEW

+168

mbedtls_mpi_sub_abs

NEW

+160

mbedtls_mpi_add_abs

NEW

+158

mbedtls_mpi_cmp_mpi

NEW

+156

ecp_group_load

NEW

+156

mbedtls_mpi_core_montmul

NEW

+152

ecp_randomize_jac

NEW

+138

mbedtls_mpi_core_random

NEW

+136

ecp_normalize_jac

NEW

+132

mbedtls_ecp_muladd_restartable

NEW

+128

ecp_sw_rhs

NEW

+124

mbedtls_ecp_check_privkey

NEW

+122

mbedtls_mpi_cmp_abs

NEW

+112

mbedtls_mpi_shrink

NEW

+108

ecp_mod_p521

NEW

+108

mbedtls_mpi_core_shift_r

NEW

+106

mbedtls_mpi_copy

NEW

+104

add_sub_mpi

NEW

+104

ecp_select_comb

NEW

+104

mbedtls_mpi_mod_mpi

NEW

+104

mbedtls_mpi_safe_cond_swap

NEW

+100

mbedtls_ecp_group_free

NEW

+96

ecp_randomize_mxz

NEW

+92

mbedtls_mpi_lsb

NEW

+92

mbedtls_mpi_mul_int

NEW

+92

mbedtls_mpi_safe_cond_assign

NEW

+90

mbedtls_mpi_core_shift_l

NEW

+88

mbedtls_mpi_core_fill_random

NEW

+86

derive_mpi

NEW

+84

mbedtls_mpi_grow

NEW

+80

ecp_safe_invert_jac

NEW

+78

mbedtls_mpi_core_lt_ct

NEW

+78

mbedtls_mpi_core_read_le

NEW

+76

ecp_mod_p255

NEW

+76

mbedtls_mpi_set_bit

NEW

+74

mbedtls_mpi_core_read_be

NEW

+72

secp521r1_T_0_X

NEW

+72

secp521r1_T_0_Y

NEW

+72

secp521r1_T_10_X

NEW

+72

secp521r1_T_10_Y

NEW

+72

secp521r1_T_11_X

NEW

+72

secp521r1_T_11_Y

NEW

+72

secp521r1_T_12_X

NEW

+72

secp521r1_T_12_Y

NEW

+72

secp521r1_T_13_X

NEW

+72

secp521r1_T_13_Y

NEW

+72

secp521r1_T_14_X

NEW

+72

secp521r1_T_14_Y

NEW

+72

secp521r1_T_15_X

NEW

+72

secp521r1_T_15_Y

NEW

+72

secp521r1_T_16_X

NEW

+72

secp521r1_T_16_Y

NEW

+72

secp521r1_T_17_X

NEW

+72

secp521r1_T_17_Y

NEW

+72

secp521r1_T_18_X

NEW

+72

secp521r1_T_18_Y

NEW

+72

secp521r1_T_19_X

NEW

+72

secp521r1_T_19_Y

NEW

+72

secp521r1_T_1_X

NEW

+72

secp521r1_T_1_Y

NEW

+72

secp521r1_T_20_X

NEW

+72

secp521r1_T_20_Y

NEW

+72

secp521r1_T_21_X

NEW

+72

secp521r1_T_21_Y

NEW

+72

secp521r1_T_22_X

NEW

+72

secp521r1_T_22_Y

NEW

+72

secp521r1_T_23_X

NEW

+72

secp521r1_T_23_Y

NEW

+72

secp521r1_T_24_X

NEW

+72

secp521r1_T_24_Y

NEW

+72

secp521r1_T_25_X

NEW

+72

secp521r1_T_25_Y

NEW

+72

secp521r1_T_26_X

NEW

+72

secp521r1_T_26_Y

NEW

+72

secp521r1_T_27_X

NEW

+72

secp521r1_T_27_Y

NEW

+72

secp521r1_T_28_X

NEW

+72

secp521r1_T_28_Y

NEW

+72

secp521r1_T_29_X

NEW

+72

secp521r1_T_29_Y

NEW

+72

secp521r1_T_2_X

NEW

+72

secp521r1_T_2_Y

NEW

+72

secp521r1_T_30_X

NEW

+72

secp521r1_T_30_Y

NEW

+72

secp521r1_T_31_X

NEW

+72

secp521r1_T_31_Y

NEW

+72

secp521r1_T_3_X

NEW

+72

secp521r1_T_3_Y

NEW

+72

secp521r1_T_4_X

NEW

+72

secp521r1_T_4_Y

NEW

+72

secp521r1_T_5_X

NEW

+72

secp521r1_T_5_Y

NEW

+72

secp521r1_T_6_X

NEW

+72

secp521r1_T_6_Y

NEW

+72

secp521r1_T_7_X

NEW

+72

secp521r1_T_7_Y

NEW

+72

secp521r1_T_8_X

NEW

+72

secp521r1_T_8_Y

NEW

+72

secp521r1_T_9_X

NEW

+72

secp521r1_T_9_Y

NEW

+70

mbedtls_mpi_random

NEW

+68

mbedtls_mpi_sub_mod

NEW

+68

secp521r1_b

NEW

+68

secp521r1_gx

NEW

+68

secp521r1_gy

NEW

+68

secp521r1_n

NEW

+68

secp521r1_p

NEW

+64

brainpoolP512r1_T_0_X

NEW

+64

brainpoolP512r1_T_0_Y

NEW

+64

brainpoolP512r1_T_10_X

NEW

+64

brainpoolP512r1_T_10_Y

NEW

+64

brainpoolP512r1_T_11_X

NEW

+64

brainpoolP512r1_T_11_Y

NEW

+64

brainpoolP512r1_T_12_X

NEW

+64

brainpoolP512r1_T_12_Y

NEW

+64

brainpoolP512r1_T_13_X

NEW

+64

brainpoolP512r1_T_13_Y

NEW

+64

brainpoolP512r1_T_14_X

NEW

+64

brainpoolP512r1_T_14_Y

NEW

+64

brainpoolP512r1_T_15_X

NEW

+64

brainpoolP512r1_T_15_Y

NEW

+64

brainpoolP512r1_T_16_X

NEW

+64

brainpoolP512r1_T_16_Y

NEW

+64

brainpoolP512r1_T_17_X

NEW

+64

brainpoolP512r1_T_17_Y

NEW

+64

brainpoolP512r1_T_18_X

NEW

+64

brainpoolP512r1_T_18_Y

NEW

+64

brainpoolP512r1_T_19_X

NEW

+64

brainpoolP512r1_T_19_Y

NEW

+64

brainpoolP512r1_T_1_X

NEW

+64

brainpoolP512r1_T_1_Y

NEW

+64

brainpoolP512r1_T_20_X

NEW

+64

brainpoolP512r1_T_20_Y

NEW

+64

brainpoolP512r1_T_21_X

NEW

+64

brainpoolP512r1_T_21_Y

NEW

+64

brainpoolP512r1_T_22_X

NEW

+64

brainpoolP512r1_T_22_Y

NEW

+64

brainpoolP512r1_T_23_X

NEW

+64

brainpoolP512r1_T_23_Y

NEW

+64

brainpoolP512r1_T_24_X

NEW

+64

brainpoolP512r1_T_24_Y

NEW

+64

brainpoolP512r1_T_25_X

NEW

+64

brainpoolP512r1_T_25_Y

NEW

+64

brainpoolP512r1_T_26_X

NEW

+64

brainpoolP512r1_T_26_Y

NEW

+64

brainpoolP512r1_T_27_X

NEW

+64

brainpoolP512r1_T_27_Y

NEW

+64

brainpoolP512r1_T_28_X

NEW

+64

brainpoolP512r1_T_28_Y

NEW

+64

brainpoolP512r1_T_29_X

NEW

+64

brainpoolP512r1_T_29_Y

NEW

+64

brainpoolP512r1_T_2_X

NEW

+64

brainpoolP512r1_T_2_Y

NEW

+64

brainpoolP512r1_T_30_X

NEW

+64

brainpoolP512r1_T_30_Y

NEW

+64

brainpoolP512r1_T_31_X

NEW

+64

brainpoolP512r1_T_31_Y

NEW

+64

brainpoolP512r1_T_3_X

NEW

+64

brainpoolP512r1_T_3_Y

NEW

+64

brainpoolP512r1_T_4_X

NEW

+64

brainpoolP512r1_T_4_Y

NEW

+64

brainpoolP512r1_T_5_X

NEW

+64

brainpoolP512r1_T_5_Y

NEW

+64

brainpoolP512r1_T_6_X

NEW

+64

brainpoolP512r1_T_6_Y

NEW

+64

brainpoolP512r1_T_7_X

NEW

+64

brainpoolP512r1_T_7_Y

NEW

+64

brainpoolP512r1_T_8_X

NEW

+64

brainpoolP512r1_T_8_Y

NEW

+64

brainpoolP512r1_T_9_X

NEW

+64

brainpoolP512r1_T_9_Y

NEW

+64

brainpoolP512r1_a

NEW

+64

brainpoolP512r1_b

NEW

+64

brainpoolP512r1_gx

NEW

+64

brainpoolP512r1_gy

NEW

+64

brainpoolP512r1_n

NEW

+64

brainpoolP512r1_p

NEW

+60

mbedtls_ecp_fix_negative

NEW

+58

add64

NEW

+56

mbedtls_ecp_group_init

NEW

+56

mbedtls_mpi_add_mod

NEW

+56

mbedtls_mpi_core_get_mont_r2_unsafe

NEW

+56

mbedtls_mpi_mul_int_mod

NEW

+56

mbedtls_mpi_resize_clear

NEW

+54

mbedtls_mpi_core_mul

NEW

+54

mbedtls_mpi_shift_l

NEW

+52

mbedtls_mpi_shift_l_mod

NEW

+50

mbedtls_mpi_lset

NEW

+48

brainpoolP384r1_T_0_X

NEW

+48

brainpoolP384r1_T_0_Y

NEW

+48

brainpoolP384r1_T_10_X

NEW

+48

brainpoolP384r1_T_10_Y

NEW

+48

brainpoolP384r1_T_11_X

NEW

+48

brainpoolP384r1_T_11_Y

NEW

+48

brainpoolP384r1_T_12_X

NEW

+48

brainpoolP384r1_T_12_Y

NEW

+48

brainpoolP384r1_T_13_X

NEW

+48

brainpoolP384r1_T_13_Y

NEW

+48

brainpoolP384r1_T_14_X

NEW

+48

brainpoolP384r1_T_14_Y

NEW

+48

brainpoolP384r1_T_15_X

NEW

+48

brainpoolP384r1_T_15_Y

NEW

+48

brainpoolP384r1_T_16_X

NEW

+48

brainpoolP384r1_T_16_Y

NEW

+48

brainpoolP384r1_T_17_X

NEW

+48

brainpoolP384r1_T_17_Y

NEW

+48

brainpoolP384r1_T_18_X

NEW

+48

brainpoolP384r1_T_18_Y

NEW

+48

brainpoolP384r1_T_19_X

NEW

+48

brainpoolP384r1_T_19_Y

NEW

+48

brainpoolP384r1_T_1_X

NEW

+48

brainpoolP384r1_T_1_Y

NEW

+48

brainpoolP384r1_T_20_X

NEW

+48

brainpoolP384r1_T_20_Y

NEW

+48

brainpoolP384r1_T_21_X

NEW

+48

brainpoolP384r1_T_21_Y

NEW

+48

brainpoolP384r1_T_22_X

NEW

+48

brainpoolP384r1_T_22_Y

NEW

+48

brainpoolP384r1_T_23_X

NEW

+48

brainpoolP384r1_T_23_Y

NEW

+48

brainpoolP384r1_T_24_X

NEW

+48

brainpoolP384r1_T_24_Y

NEW

+48

brainpoolP384r1_T_25_X

NEW

+48

brainpoolP384r1_T_25_Y

NEW

+48

brainpoolP384r1_T_26_X

NEW

+48

brainpoolP384r1_T_26_Y

NEW

+48

brainpoolP384r1_T_27_X

NEW

+48

brainpoolP384r1_T_27_Y

NEW

+48

brainpoolP384r1_T_28_X

NEW

+48

brainpoolP384r1_T_28_Y

NEW

+48

brainpoolP384r1_T_29_X

NEW

+48

brainpoolP384r1_T_29_Y

NEW

+48

brainpoolP384r1_T_2_X

NEW

+48

brainpoolP384r1_T_2_Y

NEW

+48

brainpoolP384r1_T_30_X

NEW

+48

brainpoolP384r1_T_30_Y

NEW

+48

brainpoolP384r1_T_31_X

NEW

+48

brainpoolP384r1_T_31_Y

NEW

+48

brainpoolP384r1_T_3_X

NEW

+48

brainpoolP384r1_T_3_Y

NEW

+48

brainpoolP384r1_T_4_X

NEW

+48

brainpoolP384r1_T_4_Y

NEW

+48

brainpoolP384r1_T_5_X

NEW

+48

brainpoolP384r1_T_5_Y

NEW

+48

brainpoolP384r1_T_6_X

NEW

+48

brainpoolP384r1_T_6_Y

NEW

+48

brainpoolP384r1_T_7_X

NEW

+48

brainpoolP384r1_T_7_Y

NEW

+48

brainpoolP384r1_T_8_X

NEW

+48

brainpoolP384r1_T_8_Y

NEW

+48

brainpoolP384r1_T_9_X

NEW

+48

brainpoolP384r1_T_9_Y

NEW

+48

brainpoolP384r1_a

NEW

+48

brainpoolP384r1_b

NEW

+48

brainpoolP384r1_gx

NEW

+48

brainpoolP384r1_gy

NEW

+48

brainpoolP384r1_n

NEW

+48

brainpoolP384r1_p

NEW

+48

secp384r1_T_0_X

NEW

+48

secp384r1_T_0_Y

NEW

+48

secp384r1_T_10_X

NEW

+48

secp384r1_T_10_Y

NEW

+48

secp384r1_T_11_X

NEW

+48

secp384r1_T_11_Y

NEW

+48

secp384r1_T_12_X

NEW

+48

secp384r1_T_12_Y

NEW

+48

secp384r1_T_13_X

NEW

+48

secp384r1_T_13_Y

NEW

+48

secp384r1_T_14_X

NEW

+48

secp384r1_T_14_Y

NEW

+48

secp384r1_T_15_X

NEW

+48

secp384r1_T_15_Y

NEW

+48

secp384r1_T_16_X

NEW

+48

secp384r1_T_16_Y

NEW

+48

secp384r1_T_17_X

NEW

+48

secp384r1_T_17_Y

NEW

+48

secp384r1_T_18_X

NEW

+48

secp384r1_T_18_Y

NEW

+48

secp384r1_T_19_X

NEW

+48

secp384r1_T_19_Y

NEW

+48

secp384r1_T_1_X

NEW

+48

secp384r1_T_1_Y

NEW

+48

secp384r1_T_20_X

NEW

+48

secp384r1_T_20_Y

NEW

+48

secp384r1_T_21_X

NEW

+48

secp384r1_T_21_Y

NEW

+48

secp384r1_T_22_X

NEW

+48

secp384r1_T_22_Y

NEW

+48

secp384r1_T_23_X

NEW

+48

secp384r1_T_23_Y

NEW

+48

secp384r1_T_24_X

NEW

+48

secp384r1_T_24_Y

NEW

+48

secp384r1_T_25_X

NEW

+48

secp384r1_T_25_Y

NEW

+48

secp384r1_T_26_X

NEW

+48

secp384r1_T_26_Y

NEW

+48

secp384r1_T_27_X

NEW

+48

secp384r1_T_27_Y

NEW

+48

secp384r1_T_28_X

NEW

+48

secp384r1_T_28_Y

NEW

+48

secp384r1_T_29_X

NEW

+48

secp384r1_T_29_Y

NEW

+48

secp384r1_T_2_X

NEW

+48

secp384r1_T_2_Y

NEW

+48

secp384r1_T_30_X

NEW

+48

secp384r1_T_30_Y

NEW

+48

secp384r1_T_31_X

NEW

+48

secp384r1_T_31_Y

NEW

+48

secp384r1_T_3_X

NEW

+48

secp384r1_T_3_Y

NEW

+48

secp384r1_T_4_X

NEW

+48

secp384r1_T_4_Y

NEW

+48

secp384r1_T_5_X

NEW

+48

secp384r1_T_5_Y

NEW

+48

secp384r1_T_6_X

NEW

+48

secp384r1_T_6_Y

NEW

+48

secp384r1_T_7_X

NEW

+48

secp384r1_T_7_Y

NEW

+48

secp384r1_T_8_X

NEW

+48

secp384r1_T_8_Y

NEW

+48

secp384r1_T_9_X

NEW

+48

secp384r1_T_9_Y

NEW

+48

secp384r1_b

NEW

+48

secp384r1_gx

NEW

+48

secp384r1_gy

NEW

+48

secp384r1_n

NEW

+48

secp384r1_p

NEW

+46

mbedtls_ecp_copy

NEW

+46

mbedtls_mpi_core_cond_swap

NEW

+46

mbedtls_mpi_core_sub

NEW

+46

mbedtls_mpi_core_uint_le_mpi

NEW

+44

mbedtls_ct_memcpy_if

NEW

+44

mbedtls_mpi_core_add

NEW

+44

mbedtls_mpi_core_bitlen

NEW

+42

mbedtls_ecp_set_zero

NEW

+42

mbedtls_mpi_read_binary

NEW

+42

mbedtls_mpi_read_binary_le

NEW

+38

carry64

NEW

+38

mbedtls_mpi_core_montmul_init

NEW

+36

fit::internal::target<>::invoke()

NEW

+36

mbedtls_mpi_add_int

NEW

+36

mbedtls_mpi_cmp_int

NEW

+36

mbedtls_mpi_sub_int

NEW

+32

brainpoolP256r1_T_0_X

NEW

+32

brainpoolP256r1_T_0_Y

NEW

+32

brainpoolP256r1_T_10_X

NEW

+32

brainpoolP256r1_T_10_Y

NEW

+32

brainpoolP256r1_T_11_X

NEW

+32

brainpoolP256r1_T_11_Y

NEW

+32

brainpoolP256r1_T_12_X

NEW

+32

brainpoolP256r1_T_12_Y

NEW

+32

brainpoolP256r1_T_13_X

NEW

+32

brainpoolP256r1_T_13_Y

NEW

+32

brainpoolP256r1_T_14_X

NEW

+32

brainpoolP256r1_T_14_Y

NEW

+32

brainpoolP256r1_T_15_X

NEW

+32

brainpoolP256r1_T_15_Y

NEW

+32

brainpoolP256r1_T_1_X

NEW

+32

brainpoolP256r1_T_1_Y

NEW

+32

brainpoolP256r1_T_2_X

NEW

+32

brainpoolP256r1_T_2_Y

NEW

+32

brainpoolP256r1_T_3_X

NEW

+32

brainpoolP256r1_T_3_Y

NEW

+32

brainpoolP256r1_T_4_X

NEW

+32

brainpoolP256r1_T_4_Y

NEW

+32

brainpoolP256r1_T_5_X

NEW

+32

brainpoolP256r1_T_5_Y

NEW

+32

brainpoolP256r1_T_6_X

NEW

+32

brainpoolP256r1_T_6_Y

NEW

+32

brainpoolP256r1_T_7_X

NEW

+32

brainpoolP256r1_T_7_Y

NEW

+32

brainpoolP256r1_T_8_X

NEW

+32

brainpoolP256r1_T_8_Y

NEW

+32

brainpoolP256r1_T_9_X

NEW

+32

brainpoolP256r1_T_9_Y

NEW

+32

brainpoolP256r1_a

NEW

+32

brainpoolP256r1_b

NEW

+32

brainpoolP256r1_gx

NEW

+32

brainpoolP256r1_gy

NEW

+32

brainpoolP256r1_n

NEW

+32

brainpoolP256r1_p

NEW

+32

mbedtls_ecp_point_free

NEW

+32

mbedtls_mpi_core_cond_assign

NEW

+32

mbedtls_mpi_core_sub_int

NEW

+32

mbedtls_mpi_free

NEW

+32

mbedtls_mpi_get_bit

NEW

+32

secp224k1_T_0_X

NEW

+32

secp224k1_T_0_Y

NEW

+32

secp224k1_T_10_X

NEW

+32

secp224k1_T_10_Y

NEW

+32

secp224k1_T_11_X

NEW

+32

secp224k1_T_11_Y

NEW

+32

secp224k1_T_12_X

NEW

+32

secp224k1_T_12_Y

NEW

+32

secp224k1_T_13_X

NEW

+32

secp224k1_T_13_Y

NEW

+32

secp224k1_T_14_X

NEW

+32

secp224k1_T_14_Y

NEW

+32

secp224k1_T_15_X

NEW

+32

secp224k1_T_15_Y

NEW

+32

secp224k1_T_1_X

NEW

+32

secp224k1_T_1_Y

NEW

+32

secp224k1_T_2_X

NEW

+32

secp224k1_T_2_Y

NEW

+32

secp224k1_T_3_X

NEW

+32

secp224k1_T_3_Y

NEW

+32

secp224k1_T_4_X

NEW

+32

secp224k1_T_4_Y

NEW

+32

secp224k1_T_5_X

NEW

+32

secp224k1_T_5_Y

NEW

+32

secp224k1_T_6_X

NEW

+32

secp224k1_T_6_Y

NEW

+32

secp224k1_T_7_X

NEW

+32

secp224k1_T_7_Y

NEW

+32

secp224k1_T_8_X

NEW

+32

secp224k1_T_8_Y

NEW

+32

secp224k1_T_9_X

NEW

+32

secp224k1_T_9_Y

NEW

+32

secp224k1_n

NEW

+32

secp224r1_T_0_X

NEW

+32

secp224r1_T_0_Y

NEW

+32

secp224r1_T_10_X

NEW

+32

secp224r1_T_10_Y

NEW

+32

secp224r1_T_11_X

NEW

+32

secp224r1_T_11_Y

NEW

+32

secp224r1_T_12_X

NEW

+32

secp224r1_T_12_Y

NEW

+32

secp224r1_T_13_X

NEW

+32

secp224r1_T_13_Y

NEW

+32

secp224r1_T_14_X

NEW

+32

secp224r1_T_14_Y

NEW

+32

secp224r1_T_15_X

NEW

+32

secp224r1_T_15_Y

NEW

+32

secp224r1_T_1_X

NEW

+32

secp224r1_T_1_Y

NEW

+32

secp224r1_T_2_X

NEW

+32

secp224r1_T_2_Y

NEW

+32

secp224r1_T_3_X

NEW

+32

secp224r1_T_3_Y

NEW

+32

secp224r1_T_4_X

NEW

+32

secp224r1_T_4_Y

NEW

+32

secp224r1_T_5_X

NEW

+32

secp224r1_T_5_Y

NEW

+32

secp224r1_T_6_X

NEW

+32

secp224r1_T_6_Y

NEW

+32

secp224r1_T_7_X

NEW

+32

secp224r1_T_7_Y

NEW

+32

secp224r1_T_8_X

NEW

+32

secp224r1_T_8_Y

NEW

+32

secp224r1_T_9_X

NEW

+32

secp224r1_T_9_Y

NEW

+32

secp224r1_p

NEW

+32

secp256k1_T_0_X

NEW

+32

secp256k1_T_0_Y

NEW

+32

secp256k1_T_10_X

NEW

+32

secp256k1_T_10_Y

NEW

+32

secp256k1_T_11_X

NEW

+32

secp256k1_T_11_Y

NEW

+32

secp256k1_T_12_X

NEW

+32

secp256k1_T_12_Y

NEW

+32

secp256k1_T_13_X

NEW

+32

secp256k1_T_13_Y

NEW

+32

secp256k1_T_14_X

NEW

+32

secp256k1_T_14_Y

NEW

+32

secp256k1_T_15_X

NEW

+32

secp256k1_T_15_Y

NEW

+32

secp256k1_T_1_X

NEW

+32

secp256k1_T_1_Y

NEW

+32

secp256k1_T_2_X

NEW

+32

secp256k1_T_2_Y

NEW

+32

secp256k1_T_3_X

NEW

+32

secp256k1_T_3_Y

NEW

+32

secp256k1_T_4_X

NEW

+32

secp256k1_T_4_Y

NEW

+32

secp256k1_T_5_X

NEW

+32

secp256k1_T_5_Y

NEW

+32

secp256k1_T_6_X

NEW

+32

secp256k1_T_6_Y

NEW

+32

secp256k1_T_7_X

NEW

+32

secp256k1_T_7_Y

NEW

+32

secp256k1_T_8_X

NEW

+32

secp256k1_T_8_Y

NEW

+32

secp256k1_T_9_X

NEW

+32

secp256k1_T_9_Y

NEW

+32

secp256k1_gx

NEW

+32

secp256k1_gy

NEW

+32

secp256k1_n

NEW

+32

secp256k1_p

NEW

+32

secp256r1_T_0_X

NEW

+32

secp256r1_T_0_Y

NEW

+32

secp256r1_T_10_X

NEW

+32

secp256r1_T_10_Y

NEW

+32

secp256r1_T_11_X

NEW

+32

secp256r1_T_11_Y

NEW

+32

secp256r1_T_12_X

NEW

+32

secp256r1_T_12_Y

NEW

+32

secp256r1_T_13_X

NEW

+32

secp256r1_T_13_Y

NEW

+32

secp256r1_T_14_X

NEW

+32

secp256r1_T_14_Y

NEW

+32

secp256r1_T_15_X

NEW

+32

secp256r1_T_15_Y

NEW

+32

secp256r1_T_1_X

NEW

+32

secp256r1_T_1_Y

NEW

+32

secp256r1_T_2_X

NEW

+32

secp256r1_T_2_Y

NEW

+32

secp256r1_T_3_X

NEW

+32

secp256r1_T_3_Y

NEW

+32

secp256r1_T_4_X

NEW

+32

secp256r1_T_4_Y

NEW

+32

secp256r1_T_5_X

NEW

+32

secp256r1_T_5_Y

NEW

+32

secp256r1_T_6_X

NEW

+32

secp256r1_T_6_Y

NEW

+32

secp256r1_T_7_X

NEW

+32

secp256r1_T_7_Y

NEW

+32

secp256r1_T_8_X

NEW

+32

secp256r1_T_8_Y

NEW

+32

secp256r1_T_9_X

NEW

+32

secp256r1_T_9_Y

NEW

+32

secp256r1_b

NEW

+32

secp256r1_gx

NEW

+32

secp256r1_gy

NEW

+32

secp256r1_n

NEW

+32

secp256r1_p

NEW

+32

x25519_bad_point_1

NEW

+32

x25519_bad_point_2

NEW

+30

mbedtls_mpi_core_bigendian_to_host

NEW

+30

mbedtls_mpi_core_from_mont_rep

NEW

+28

curve448_part_of_n

NEW

+28

mbedtls_ecp_point_init

NEW

+28

mbedtls_platform_zeroize

NEW

+28

secp224k1_gx

NEW

+28

secp224k1_gy

NEW

+28

secp224k1_p

NEW

+28

secp224r1_b

NEW

+28

secp224r1_gx

NEW

+28

secp224r1_gy

NEW

+28

secp224r1_n

NEW

+26

mbedtls_mpi_core_exp_mod_working_limbs

NEW

+24

mbedtls_mpi_core_check_zero_ct

NEW

+24

mbedtls_zeroize_and_free

NEW

+24

mpi_free_many

NEW

+24

mpi_init_many

NEW

+24

secp192k1_T_0_X

NEW

+24

secp192k1_T_0_Y

NEW

+24

secp192k1_T_10_X

NEW

+24

secp192k1_T_10_Y

NEW

+24

secp192k1_T_11_X

NEW

+24

secp192k1_T_11_Y

NEW

+24

secp192k1_T_12_X

NEW

+24

secp192k1_T_12_Y

NEW

+24

secp192k1_T_13_X

NEW

+24

secp192k1_T_13_Y

NEW

+24

secp192k1_T_14_X

NEW

+24

secp192k1_T_14_Y

NEW

+24

secp192k1_T_15_X

NEW

+24

secp192k1_T_15_Y

NEW

+24

secp192k1_T_1_X

NEW

+24

secp192k1_T_1_Y

NEW

+24

secp192k1_T_2_X

NEW

+24

secp192k1_T_2_Y

NEW

+24

secp192k1_T_3_X

NEW

+24

secp192k1_T_3_Y

NEW

+24

secp192k1_T_4_X

NEW

+24

secp192k1_T_4_Y

NEW

+24

secp192k1_T_5_X

NEW

+24

secp192k1_T_5_Y

NEW

+24

secp192k1_T_6_X

NEW

+24

secp192k1_T_6_Y

NEW

+24

secp192k1_T_7_X

NEW

+24

secp192k1_T_7_Y

NEW

+24

secp192k1_T_8_X

NEW

+24

secp192k1_T_8_Y

NEW

+24

secp192k1_T_9_X

NEW

+24

secp192k1_T_9_Y

NEW

+24

secp192k1_gx

NEW

+24

secp192k1_gy

NEW

+24

secp192k1_n

NEW

+24

secp192k1_p

NEW

+24

secp192r1_T_0_X

NEW

+24

secp192r1_T_0_Y

NEW

+24

secp192r1_T_10_X

NEW

+24

secp192r1_T_10_Y

NEW

+24

secp192r1_T_11_X

NEW

+24

secp192r1_T_11_Y

NEW

+24

secp192r1_T_12_X

NEW

+24

secp192r1_T_12_Y

NEW

+24

secp192r1_T_13_X

NEW

+24

secp192r1_T_13_Y

NEW

+24

secp192r1_T_14_X

NEW

+24

secp192r1_T_14_Y

NEW

+24

secp192r1_T_15_X

NEW

+24

secp192r1_T_15_Y

NEW

+24

secp192r1_T_1_X

NEW

+24

secp192r1_T_1_Y

NEW

+24

secp192r1_T_2_X

NEW

+24

secp192r1_T_2_Y

NEW

+24

secp192r1_T_3_X

NEW

+24

secp192r1_T_3_Y

NEW

+24

secp192r1_T_4_X

NEW

+24

secp192r1_T_4_Y

NEW

+24

secp192r1_T_5_X

NEW

+24

secp192r1_T_5_Y

NEW

+24

secp192r1_T_6_X

NEW

+24

secp192r1_T_6_Y

NEW

+24

secp192r1_T_7_X

NEW

+24

secp192r1_T_7_Y

NEW

+24

secp192r1_T_8_X

NEW

+24

secp192r1_T_8_Y

NEW

+24

secp192r1_T_9_X

NEW

+24

secp192r1_T_9_Y

NEW

+24

secp192r1_b

NEW

+24

secp192r1_gx

NEW

+24

secp192r1_gy

NEW

+24

secp192r1_n

NEW

+24

secp192r1_p

NEW

+22

mbedtls_mpi_core_to_mont_rep

NEW

+20

fit::internal::inline_trivial_target_move<>()

NEW

+20

fit::internal::target<>::ops

NEW

+20

mbedtls_ecdsa_verify

NEW

+20

mbedtls_mpi_shift_r

NEW

+16

curve25519_part_of_n

NEW

+16

ecp_mod_p192k1

NEW

+16

ecp_mod_p224k1

NEW

+16

ecp_mod_p256k1

NEW

+16

mbedtls_calloc

NEW

+16

mbedtls_ecp_is_zero

NEW

+16

mbedtls_free

NEW

+12

mbedtls_mpi_bitlen

NEW

+12

mbedtls_mpi_size

NEW

+12

mbedtls_mpi_sub_mpi

NEW

+10

mbedtls_mpi_add_mpi

NEW

+8

ecp_mod_p192k1.Rp

NEW

+8

ecp_mod_p224k1.Rp

NEW

+8

ecp_mod_p256k1.Rp

NEW

+8

ecp_x25519_bad_point_1

NEW

+8

ecp_x25519_bad_point_2

NEW

+8

mbedtls_mpi_init

NEW

+4

memset_func

NEW

+4

mpi_one

NEW

+4

platform_calloc_uninit

NEW

+4

platform_free_uninit

NEW

+4

secp192k1_a

NEW

+4

secp192k1_b

NEW

+4

secp224k1_a

NEW

+4

secp224k1_b

NEW

+4

secp256k1_a

NEW

+4

secp256k1_b

NEW

+2

fit::internal::inline_target_get()

+47,808

RAM

+8

[section .data]

NEW

+56

ecp_supported_grp_id

NEW

+4

add_count

NEW

+4

dbl_count

NEW

+4

mbedtls_calloc_func

NEW

+4

mbedtls_ecp_grp_id_list.init_done

NEW

+4

mbedtls_free_func

NEW

+4

mul_count

+88

API reference#

Moved: pw_crypto