libtomcrypt is a pleasure to work with: the code is clean, readable, and things are well laid-out. One the few things I disliked was how ECC keys are represented internally:
typedef struct {
void *x, *y, *z;
} ecc_point;
/** An ECC key */
typedef struct {
/** Type of key, PK_PRIVATE or PK_PUBLIC */
int type;
[...]
/** The public key */
ecc_point pubkey;
/** The private key */
void *k;
} ecc_key;
If type
is PK_PUBLIC
, the private component of the key should probably be
NULL.
I think this is suboptimal and potentially confusing. It seems to me that
the following would be better:
struct ecc_public_key {
void *x, *y, *z;
};
struct ecc_private_key {
struct ecc_public_key public;
void* k;
};
Introducing 2 different types for public and private keys allows us to be more
specific with our type requirements. For example the function
ecc_shared_secret
looks like that:
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
unsigned char *out, unsigned long *outlen);
A new API could enforce the key’s type more easily:
int ecc_shared_secret(const struct ecc_private_key *private_key,
const struct ecc_public_key *public_key,
unsigned char *out, unsigned long *outlen);
This way you can get rid of checks at the beginning of some functions, like this one:
/* type valid? */
if (private_key->type != PK_PRIVATE) {
return CRYPT_PK_NOT_PRIVATE;
}
Now the key type is explicit, private keys will only be struct
ecc_private_key
, public ones struct ecc_public_key
. If you want to be able to
pass both keys types, you can do something like this:
int ecc_some_function(struct ecc_public_key* public, void* private, ...);
And pass the private component of the key manually.