named-data-iot/ndn-lite

Use micro-ecc 'static' branch

Closed this issue · 7 comments

micro-ecc library used in security-backend has two variants:

The 'static' branch has smaller binary code size, lower memory usage, and faster execution.

In typical IoT use case, it's rarely necessary to support multiple ECC curves. Therefore, NDN-Lite should switch to micro-ecc 'static' branch, and statically select secp256r1 curve that is the default setting in other libraries including ndn-cxx and PyNDN.

Hi Junxiao, I think I'm still little unclear about this. Which one you are suggesting?

  • Using secp256r1 (with micro-ecc 'static' branch) in default security-backend while remaining security-frontend interfaces supporting multiple curves (and not work with default backend).
  • Using secp256r1 exclusively in NDN-Lite (no choice at all).
  • uECC is switched to support secp256r1 only.
  • Default security backend only supports secp256r1, and returns error code for any other curve.
  • Security frontend may continue to offer other curves, but they would work only if an alternate security backend is loaded.

I just reviewed security backend. Current NDN-Lite includes two libraries micro-ecc and tinycrypt. Tinycrypt has all functions micro-ecc has but only use p256 curve in ECC operation, and that's why we also use micro-ecc. Given that, I wonder if we can use tinycrypt only and remove micro-ecc entirely (if possible). This can be reserved for future.

Tinycrypt has all functions micro-ecc has

TinyCrypt lacks ECC key generation feature.
Its ECC code is partially a copy of micro-ecc static branch, as evidenced by uECC in function names.

TinyCrypt lacks ECC key generation feature.

It seems TinyCrypt has ECC key generation function?

Its ECC code is partially a copy of micro-ecc static branch

Yes, they claim in documentation that their ECC implementation is based on micro-ecc and their APIs look alike also, thus easy to switch to.

Nevertheless, NDN-Lite should first switch to micro-ecc 'static', then consider the usage of TinyCrypt?

It seems TinyCrypt has ECC key generation function?

Yes indeed. I didn't look into tc_ecc_dh.h file.

Nevertheless, NDN-Lite should first switch to micro-ecc 'static', then consider the usage of TinyCrypt?

There are trade-offs.
uECC 'static' is a single curve implementation.
tc_ecc is a copy of uECC 'master', which is a multi curve implementation that has larger code size than single curve.
Nevertheless, even with a multi curve implementation, compiler would be able to optimize away unused curves, if it can prove the codepath is never invoked.

What really makes things worse is switch statement like this:

case NDN_ECDSA_CURVE_SECP160R1:
curve = uECC_secp160r1();
break;
case NDN_ECDSA_CURVE_SECP192R1:
curve = uECC_secp192r1();
break;
case NDN_ECDSA_CURVE_SECP224R1:
curve = uECC_secp224r1();
break;
case NDN_ECDSA_CURVE_SECP256R1:
curve = uECC_secp256r1();
break;
case NDN_ECDSA_CURVE_SECP256K1:
curve = uECC_secp256k1();
break;

Compiler cannot prove some curves are unused because they could be triggered by received packets, so they have to be included in the binary.

Thus, there are two choices moving forward.
One is to select a single curve implementation, i.e. uECC 'static' secp256r1, which is the default in other libraries.
The other is to delete some of the case branches, and only keep secp224r1 and secp256r1. These two curves overlap with ndn-cxx's support, while the other curves are unlikely to be seen in the wild.

You can even pursue both choices, by making two ECC backends.

@Zhiyi-Zhang Hi Zhiyi, I wonder your opinions here?