open-quantum-safe / liboqs

C library for prototyping and experimenting with quantum-resistant cryptography
https://openquantumsafe.org/
Other
1.78k stars 436 forks source link

Non-fixed key sizes for signature schemes #297

Closed manvari closed 5 years ago

manvari commented 6 years ago

In sig/sig.h, the OQS_SIG structure expects fixed sizes for public and private keys (priv_key_len and pub_key_len). These sizes are to be set when an instance of the signature algorithm is created via a call to OQS_new, and are then used to allocate sufficient memory for keys before calling the algorithm's keygen method. However, some QS signature schemes have varying key sizes (e.g. NIST candidate Falcon, which features optional compression for private keys).

Considering this, it could be better to let the algorithm's keygen method modify the key size fields appropriately. This would also require adding a max_key_len field to OQS_SIG so as to enable the caller to allocate memory before the keygen method is called.

dstebila commented 6 years ago

Hi Maxime! Thanks for the feedback. We're actually working on a revision of our signature API to simplify the OQS_SIG structure and to bring it closer to the NIST/SUPERCOP API. We should have a candidate version of the new API for feedback in the next week or so -- @christianpaquin has been working on it. I'll post a comment here once we've got something for you to look at.

manvari commented 6 years ago

Sure, I will look at the new API when it rolls out. In the meantime, I'll be checking for updates to the master-new-api branch. :)

dstebila commented 6 years ago

@manvari does the current status of #298 satisfy your concerns in this issue?

manvari commented 6 years ago

@dstebila I have mixed feelings about this one!

The signature API changes introduced by @christianpaquin in #298 help OQS stick to the NIST API. This definitely is the way to go, considering all NIST submissions conform to this API. This makes integrating these submissions into OQS very easy; only a thin wrapper, with no superfluous parameters added, is required.

On the other hand, by fully adhering to the NIST API, we get to miss out on some of the optimizations that submission authors may have made. In the case of this issue, that would be forgoing shorter public/private keys even though the underlying algorithm may offer them. I have two possible solutions in mind:

  1. Add a void *options argument to the algorithm's keypair function in OQS_SIG, where the data to pass is defined in the algorithm's OQS integration (src/sig/sig_{algname}.h, presumably).[*] Then, a first call to the keypair with public_key and secret_key set to NULL along with a valid options argument would modify options to indicate actual key sizes. A second call with the modified options argument and non-NULL values for public_key and secret_key will then generate the keypair.
    This method is transparent w.r.t. the NIST API, since the caller will already have allocated sufficient memory before the second call to keypair. Then, for this second call, all the keypair wrapper has to do is calling the submission's crypto_keypair implementation.
    For users who do not wish to use any options, they may just generate a keypair by setting options to NULL and {public,private}_key to non-NULL values. This mimics the way libOQS currently works.
    Thinking about it, we could also add similar options for both sign and sign_open wrappers if the algorithm uses extra data for signature generation/verification (compared to the NIST API).
    [*] For example, a structure named oqs_{algname}_keypair_extradata containing fields int compress_privkey and int compress_pubkey if the algorithm supports compressing both private and public keys.

  2. Reintroduce a void *ctx field in OQS_SIG: this would also allow instantiating an algorithm with extra data, but we'd have to work around the NIST API to make sure we can still respect the prototypes of its signature-related functions.

Note: because all submissions had to respect the NIST API, I suppose some of them either had to work around it cleverly, or disable options/optimizations, or both. An interesting example of this is given in the Falcon specs, §3.11.6. Hopefully, interfacing the NIST API with libOQS' can help rectify things.

dstebila commented 6 years ago

Would every implementation know how to interpret inputs in either the compressed or uncompressed format? If no, then I would tend to think of them as "different schemes" because they are not binary compatible.

xvzcf commented 5 years ago

Closing this as the NIST branch is being deprecated.