covert-encryption / covert

An encryption format offering better security, performance and ease of use than PGP. File a bug if you found anything where we are worse than our competition, and we will fix it.
41 stars 10 forks source link

New Python bindings to Monocypher and use it for EC cryptography #63

Open covert-encryption opened 2 years ago

covert-encryption commented 2 years ago

Covert should switch to the Monocypher library for elliptic curve operations because libsodium is lacking much required functionality such as Dirty Elligator 2 (no, despite the name that is not an unclassy movie flick). Currently we have a plain Python implementation for all the algorithms needed but a C library provides better performance and higher security (also better than current libsodium bindings can).

Currently there are two existing bindings which have not been updated since Summer 2020 and which thus lack the features needed: https://github.com/eugene-eeo/monocypher-py https://github.com/jetperch/pymonocypher

It should be investigated whether anything can be salvaged of them (Python CFFI has also changed much), and if necessary an all new binding created. Fortunately the library is a simple, single file, plain C implementation, which should make the raw bindings easy. Additional wrappers will be necessary to support good Pythonic style, while still staying close to the original API, so there is still quite a bit of work needed.

covert-encryption commented 2 years ago

The first one seems quite usable, using modern CFFI and actually having the lib of the latest version, so all raw C functions are available to Python. Problems are that Python wrappers are missing for some, and are using bytes (non-zeroable) for all functions that return any buffers.

covert-encryption commented 2 years ago

@LoupVaillant Looks like Monocypher contains most of the functionality we need to only use it for all EC functionality. Two things that are missing are SHA-512 hashing (for standards-compliant Ed25519) and the XEdDSA signature.

XEd25519 would be well suited for the library given that it is mainly based on Curve25519 anyway, although that too will require implementation of SHA-512 to be compliant, and key conversion to Ed25519, then making it very similar to the existing EdDSA. The Python implementation in https://github.com/covert-encryption/covert/blob/main/covert/elliptic/xeddsa.py is based on what Signal does with the sign, despite that not being mentioned in their specification.

Would you be interested in making another release of Monocypher with such added functionality?

covert-encryption commented 2 years ago

crypto_from_eddsa_private also lacks a version that would allow hash vtable, and is hardcoded to use Blake2b. Really need all of these using SHA-512.

LoupVaillant commented 2 years ago

I deemed the private key conversion function trivial enough that I didn’t need to exposed a vtable based version. (Edit: now that I think of it, I should probably add it for consistency.)

More to the point, the optional files already contain that conversion for SHA-512.

covert-encryption commented 2 years ago

@LoupVaillant covert-web is now using Monocypher for dirty elligator and it looks like we can do that in Python soon, too.

A big issue that remains is the XEdDSA implementation, which shouldn't be too difficult to add if you'd be willing to make an update. Other minor "nice to have" things would be undirtying of points and testing for validity (not higher than p, on curve, prime subgroup, not low order). Useful for testing that the keys input from command line are correct before accepting them, as well as being able to restore the original public key bytes after Dirty Elligator, and not only "undirtying" after ECDH. We can easily afford an extra scalarmult there.

covert-encryption commented 2 years ago

The incremental API on XEdDSA signatures won't be necessary, as all modern implementations should be first hashing the data and then signing the hash value (as the message of the signature), and will never have larger messages to sign, so there is no need for all the complexity of multiple passes etc.

LoupVaillant commented 2 years ago

Given the way my code is organised, XEdDSA will almost certainly hook itself into the incremental, custom hash API first (everything else is implemented in terms of that). If I list what I’d have to support:

That will likely cost more than 25 lines of code. That’s a tough call: on the one hand I want to keep bloat to a strict minimum. On the other hand, you do have a legitimate use case. What gives me the most pause here is that it’s mostly a backwards compatibility thing, which was not an original goal of Monocypher: XEdDSA is only needed when you need to be compatible with existing X25519 keys, and add signatures after the fact. If you could generate keys from the outset, you could start from Edwards instead.

I’ll consider it, but I’m still hesitant.