-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NIST elliptic curves via mirage-crypto-ec #101
Conversation
3174b26
to
c00c7ac
Compare
This is an import of https://github.com/mirage/fiat from commit 341318ad08b9224c87ed4bd26b29cebb46e10812 (with a rename of fiat_p256 to mirage_crypto_ec). The motivation is to extend "fiat-p256" in multiple dimensions: more curves (NIST, ..), and also ECDSA - which requires hash functions, and computation of a deterministic k (RFC 6979) which is already part of this repository. Co-Authored-By: Nathan Rebours <[email protected]> Co-Authored-By: Etienne Millon <[email protected]> Co-Authored-By: Clément Pascutto <[email protected]>
ced07ac
to
d18d2d8
Compare
If you're already using dune and OCaml, perhaps you want to depend on our opam package which installs the relevant binaries to |
@JasonGross thanks for your pointer to the opam package. This sounds like a nice way forward on documenting (and running) how to re-do the extraction. For the common OCaml user, I don't think it is reasonable to generate the C code themselves (but instead we'll ship pre-generated C code). |
Indeed, I was just suggesting that perhaps your makefile setup, presumably there for documentation / regeneration purposes, can be configured for the opam-based setup rather than assuming fiat-crypto in a parent directory. |
94467d8
to
ecb3e3d
Compare
.cirrus.yml
Outdated
dependencies_script: eval `opam env` && opam pin add -y mirage-crypto.dev . && opam pin add -y mirage-crypto-rng.dev . && opam pin add -y mirage-crypto-pk.dev . && opam pin add -y mirage-crypto-ec.dev . && opam install -y -t --deps-only mirage-crypto mirage-crypto-rng mirage-crypto-pk mirage-crypto-ec | ||
build_script: eval `opam env` && opam exec -- dune build -p mirage-crypto,mirage-crypto-rng,mirage-crypto-pk,mirage-crypto-ec | ||
test_script: eval `opam env` && opam exec -- dune runtest -p mirage-crypto,mirage-crypto-rng,mirage-crypto-pk,mirage-crypto-ec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: the eval is not necessary here as the various opam commands will add the right env variables
current status:
Left items:
Delayed until later:
Reviews / comments / feedback appreciated :) [a different step / PR is to integrate 25519 (ECDH & EdDSA) and 448 (ECDH & EdDSA)] |
I added priv/pub_to/of_cstruct, and with hannesm/ocaml-x509@c063ff7 I can successfully decode & encode PKCS8 (private key) data. |
CAMLprim value mc_p224_sub(value out, value a, value b) | ||
{ | ||
CAMLparam3(out, a, b); | ||
fiat_p224_sub(Caml_ba_data_val(out), Caml_ba_data_val(a), Caml_ba_data_val(b)); | ||
CAMLreturn(Val_unit); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of the C calls of this class could be marked noalloc
since they never raise or allocate values in the C binding. That would save some overhead in calling them.
However, if the fiat functions are very CPU intensive, it may be better to leave them as alloc functions and release the global runtime lock instead during the actual C crypto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uhm, this is done at the OCaml declaration-side (e.g. for P-224 at https://github.com/mirage/mirage-crypto/pull/101/files#diff-b65c54aec12f050b8540b66b5b49e4fc2289e3137ec35bd9a7ef23f9dec38ec8R611-R638). Anything else that is needed there, or any occassion I forgot to mark [@@noalloc]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Essentially the question above: if these are computationally intensive and could take some time, then we should drop the runtime lock and not make them noalloc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Essentially the question above: if these are computationally intensive and could take some time, then we should drop the runtime lock and not make them noalloc.
It should be easy due to the use of non-relocatable bigarrays.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CPU-intensive is a comparative term. Certainly these functions are the CPU-hotspots in performing curve operations, but the time spent in any single invocation is quite small. The are some numbers in Andres Erbsen, Jade Philipoom, Jason Gross, Robert Sloan, Adam Chlipala. Simple High-Level Code For Cryptographic Arithmetic -- With Proofs, Without Compromises. Proceedings of the IEEE Symposium on Security & Privacy 2019 (S&P'19). May 2019. The table on page 10 shows that running the entire scalar multiplication (which will call these functions a handful of times) takes about 1k--3k CPU cycles. The plot in in Fig. 10 corresponds to 1000 sequential
computations of a 256-bit Montgomery ladder, and even the slowest (~500 bit primes on 32-bit machines) amount to less than 0.001--0.01 seconds per call.
Additionally, these primitives are low-level, intended to be used to implement higher-level curve operations. I expect that the boundary of these functions is not the place to be releasing runtime locks, and that should instead happen at the boundary of the curve-level operations (which, I believe, should also not be allocating anything on the heap). Another point in this direction is that ideally we'd like to generate the curve-level operations in C as well and expose that API, rather than this lower-level one.
34c6359
to
53c6363
Compare
724b2a6
to
1243e85
Compare
@EduardoRFS any idea what the root cause of the cross compile failures is? are they temporary? |
This includes: - ECDSA implementation with blinding - tests from RFC 6979 (deterministic k) - wycheproof tests for ECDH and ECDSA (commit 2196000605e45d91097147c9c71f26b72af58003) - ec/native contains a Makefile which runs the extraction (using fiat-crypto's word-by-word-montgomery)
this is ready to be merged: some initial documentation is included in this PR, also the P521 32bit code has been generated and added. I squashed the development commits together, and am fine with the remaning ones. from the comment above, future PRs may:
|
@hannesm yeah they're, github actions connections seems to be failing, will be addressing it tomorrow, feel free to ignore it |
…ge-crypto-rng, mirage-crypto-rng-mirage and mirage-crypto-rng-async (0.9.0) CHANGES: - Elliptic curve support in the new package mirage-crypto-ec The arithmetic code is generated by [fiat-crypto](https://github.com/mit-plv/fiat-crypto), a development in Coq which includes proofs of constant time behaviour. The generation can be reproduced (see ec/native/GNUmakefile). The group operation implementations are taken from BoringSSL. The high-level mechanisms (signature DSA and key exchange ECDH) are implemented in OCaml. The ECDSA implementation (as our DSA one) uses a deterministic k (RFC 6979). The NIST curves P224 (SECP224R1), P256 (SECP256R1), P384 (SECP384R1), and P521 (SECP521R1) are supported (ECDH and ECDSA), in addition to Curve25519 (X25519 and Ed25519). Performance of X25519 has been measured and is roughly the same as the hacl_x25519 and also the hacl opam package (see mirage/mirage-crypto#107 for numbers). Tests vectors are from RFCs and wycheproof. Import mirage/fiat repository (@pascutto @emillon @NathanReb @hannesm mirage/mirage-crypto#101) Check bounds of message (reported by @greg42, fixed by @hannesm mirage/mirage-crypto#108) Remove blinding, since constant time arithmetics is used (@hannesm mirage/mirage-crypto#106) Curve 25519 (X25519 & Ed25519) support (@hannesm mirage/mirage-crypto#107 imported from BoringSSL) Partially reviewed by @JasonGross @avsm @dinosaure Partially sponsored by Nitrokey GmbH
This PR integrated elliptic curves into this repository. It is based on fiat, and due to some dependencies for ECDSA (compute
k
in a deterministic way, hash algorithms) it has been imported into this repository.The API (Mirage_crypto_ec) is not yet set into stone (multiple NIST curves should be reflected, documentation is lacking). It is work in progress, with the main goal here to test with the various CI systems in place.
The extraction process (from fiat-crypto) is done via
GNUmakefile
inec/native
. Note that it has been updated, and the fiat-crypto provided inversion is used now (previously, there was afe_inv
). The test cases pass, though ECDSA may need someCstruct.rev
adaptions, and more tests (from wycheproof) are needed for ECDSA.Hope that @NathanReb @emillon @pascutto are fine with the code import here.
Sponsored by: Nitrokey GmbH