Skip to content
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

Import NI modules of GHASH from pnmadelaine_aes branch and adds specific proofs #942

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

mamonet
Copy link
Member

@mamonet mamonet commented Apr 26, 2024

This PR imports NI modules of GHASH from pnmadelaine_aes branch and adds specific proofs. However, the proofs use properties and definitions from Vale modules so there's still some work left before this PR can be merged.

  • Galois field 2^128 abstraction (can be cloned from Vale modules since portable and Vale implementations utilize same properties)
  • Equivalence lemmas of Vale specification and spec/Spec.GF128 module.
  • M32 support for GHASH (can be added in a follow-up PR)

Copy link

github-actions bot commented Apr 26, 2024

[CI] Important!
The code in dist/gcc-compatible, dist/msvc-compatible, and dist/wasm
is tested on cryspen/hacl-packages.
dist is not automatically re-generated, be sure to do it manually.
(A fresh snapshot can also be downloaded from CI by going to the "artifacts" section of your run.)
Then check the following tests before merging this PR.
Always check the latest run, it corresponds to the most recent version of this branch.
All jobs are expected to be successful.
In some cases manual intervention is needed. Please ping the hacl-packages maintainers.

  • Build, Test, Benchmark: Build on Linux (x86, x64), Windows (x86, x64), MacOS (x64, arm64), s390x, Android (arm64) and test on Linux (x86, x64), Windows (x86, x64), MacOS (x64).
  • Performance Regression Tests: Navigate to the terminal output in “Run benchmarks”. The comparison with the main branch will be at the bottom. The run fails if the performance regresses too much.
  • OCaml bindings: Build & Tests
  • JS bindings: Build & Tests
  • Rust bindings: Build & Tests

@msprotz
Copy link
Contributor

msprotz commented Apr 26, 2024

Can you say more about why you want to clone from Vale? If the specs are there and are ok, can we make sure there's no copy-paste?

@mamonet
Copy link
Member Author

mamonet commented Apr 26, 2024

I had concerns that we need to remove the dependencies to Vale modules but it turned out it's ok so there's no need to do any abstraction.

@mamonet mamonet requested a review from msprotz May 25, 2024 18:05
@mamonet mamonet marked this pull request as ready for review May 25, 2024 18:05
@mamonet mamonet requested a review from a team as a code owner May 25, 2024 18:05
@mamonet
Copy link
Member Author

mamonet commented May 26, 2024

@msprotz Missing equivalent lemmas are added in Vale.Math.Poly2.Galois module, and utilized to complete GHASH proofs. M32 is still not supprted but NI version is ready for review.

@franziskuskiefer
Copy link
Member

@msprotz What's the state of this one?

Copy link
Contributor

@msprotz msprotz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great step in the right direction. For now, we need to improve the API, understand what needs to be public and/or private, and write proper documentation about how to use this module.

Seeing how to improve the proofs would also be a plus, as this is going to add quite a bit to the maintenance effort going forward.


#include "libintvector.h"

void Hacl_Gf128_NI_gcm_init(Lib_IntVector_Intrinsics_vec128 *ctx, uint8_t *key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pnmadelaine can you please suggest names for all of these functions?


#include "libintvector.h"

void Hacl_Gf128_NI_gcm_init(Lib_IntVector_Intrinsics_vec128 *ctx, uint8_t *key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mamonet we need a comment here that answers the following questions:

  • how does one obtain a ctx? which function should one use to allocate it?
  • is the key expanded? or not? what is the length of the key? (this also applies to your other PR -- you should specify the length of the pointers your receive -- again, please look at the bignum modules for how to write good effective documentation)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a layout for GHASH context, I hope it makes it clear to understand the procedure underneath.

uint8_t *text
);

extern void
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this a function pointer?

void Hacl_Gf128_NI_gcm_init(Lib_IntVector_Intrinsics_vec128 *ctx, uint8_t *key);

void
Hacl_Gf128_NI_gcm_update_blocks(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the expected usage of this API? the documentation should tell me which functions to call, in which order, and how to obtain the final result

Copy link
Member Author

@mamonet mamonet Jun 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, not point of having a duplicate function in API. Input message is supposed to be padded anyways.

uint8_t *x2
);

void Hacl_Gf128_NI_gcm_emit(uint8_t *tag, Lib_IntVector_Intrinsics_vec128 *ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again I think @pnmadelaine called it digest or something -- it should have the same name as poly1305

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function just copies hash state to output buffer, it doesn't involve any computations. is digest more convenient in this case?

let load_elem (b:lbytes 16) : elem = load_felem_be #gf128 b
let store_elem (e:elem) : lbytes 16 = store_felem_be #gf128 e

let irred_le = mk_int #U128 #SEC 0x87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does lemean? lesser or equal? comments please

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

le here stands for little-endian mode. I will adds a comment that clears things up.

let gmul (text:bytes) (h:lbytes size_block) : Tot tag =
let acc, r = gf128_init h in
let acc = gf128_update text acc r in
decode acc
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this shown anywhere to be equivalent to the vale version?



let gf128_update_multi_mul_add_lemma_load_acc_aux a0 b0 b1 b2 b3 r =
admit();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please give us an update on how many admit()s are left and to what extent they are fixable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This and others (if any) got to be uploaded without being seen. I will address this one and lookup for other potential admits


#push-options "--z3rlimit 20 --max_fuel 0"
let logxor_disjoint #n a b m =
assert (forall (i:nat{n - m <= i /\ i < n}).{:pattern (index #bool #n (to_vec a) i)}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you familiar with calc statements? they might make this sort of proof a lot more readable

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is ported from logor_disjoint in FStar.UInt.fst https://github.com/FStarLang/FStar/blob/master/ulib/FStar.UInt.fst#L302
The body of the function was hand-copied from there, I still can improve the syntax for better readability.

(shift a1 64) +. a0 +. (shift b1 64 +. b0);
== {lemma_add_associate ((shift a1 64) +. a0) (shift b1 64) b0}
((shift a1 64) +. a0 +. shift b1 64) +. b0;
== {lemma_add_commute (shift a1 64) a0}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't a lot of these be done with the semiring tactic? that sounds very labor intensive doing all of these steps by hand

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I learn about semiring tactic? or where can I look for example?

@mamonet
Copy link
Member Author

mamonet commented Jun 21, 2024

@msprotz Thanks for reviewing the code, I agree that documentation for AES-GCM API should be in-depth and more helpful for the user. I will see how I can put such doc up tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Merge GHASH into hacl-star upstream
3 participants