From e70711c8a303c44fece7d589bfd0b0f1301be6b8 Mon Sep 17 00:00:00 2001 From: Lucas Franceschino Date: Tue, 14 May 2024 17:24:49 +0200 Subject: [PATCH] chore: regenerate patches (#277) --- proofs/fstar/extraction-edited.patch | 14568 ++++++++-------- .../fstar/extraction-secret-independent.patch | 2431 +-- .../Libcrux.Digest.Incremental_x4.fsti | 2 +- 3 files changed, 8532 insertions(+), 8469 deletions(-) diff --git a/proofs/fstar/extraction-edited.patch b/proofs/fstar/extraction-edited.patch index 02dc7b25c..e5ae54638 100644 --- a/proofs/fstar/extraction-edited.patch +++ b/proofs/fstar/extraction-edited.patch @@ -1,6 +1,6 @@ diff -ruN extraction/BitVecEq.fst extraction-edited/BitVecEq.fst ---- extraction/BitVecEq.fst 1970-01-01 01:00:00 -+++ extraction-edited/BitVecEq.fst 2024-05-07 18:38:45 +--- extraction/BitVecEq.fst 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-edited/BitVecEq.fst 2024-05-14 15:56:45.444356187 +0200 @@ -0,0 +1,12 @@ +module BitVecEq + @@ -15,8 +15,8 @@ diff -ruN extraction/BitVecEq.fst extraction-edited/BitVecEq.fst + + diff -ruN extraction/BitVecEq.fsti extraction-edited/BitVecEq.fsti ---- extraction/BitVecEq.fsti 1970-01-01 01:00:00 -+++ extraction-edited/BitVecEq.fsti 2024-05-07 18:38:45 +--- extraction/BitVecEq.fsti 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-edited/BitVecEq.fsti 2024-05-14 15:56:45.440356253 +0200 @@ -0,0 +1,294 @@ +module BitVecEq +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -312,9 +312,44 @@ diff -ruN extraction/BitVecEq.fsti extraction-edited/BitVecEq.fsti + (ensures int_arr_bitwise_eq_range arr1 d arr2 d (n_offset1 * d) (n_offset2 * d) bits) + = admit () +*) +diff -ruN extraction/Libcrux.Digest.fsti extraction-edited/Libcrux.Digest.fsti +--- extraction/Libcrux.Digest.fsti 2024-05-14 15:56:45.396356975 +0200 ++++ extraction-edited/Libcrux.Digest.fsti 2024-05-14 15:56:45.433356368 +0200 +@@ -3,13 +3,29 @@ + open Core + open FStar.Mul + ++val shake128x4_256_ (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) ++ : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ + val sha3_256_ (payload: t_Slice u8) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + + val sha3_512_ (payload: t_Slice u8) + : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) + +-/// SHAKE 256 +-/// The caller must define the size of the output in the return type. ++val shake128 (v_LEN: usize) (data: t_Slice u8) ++ : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ + val shake256 (v_LEN: usize) (data: t_Slice u8) + : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ ++val shake128x4_portable (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) ++ : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ ++val shake128x4 (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) ++ : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) ++ Prims.l_True ++ (fun _ -> Prims.l_True) diff -ruN extraction/Libcrux.Digest.Incremental_x4.fsti extraction-edited/Libcrux.Digest.Incremental_x4.fsti ---- extraction/Libcrux.Digest.Incremental_x4.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Digest.Incremental_x4.fsti 1970-01-01 01:00:00 +--- extraction/Libcrux.Digest.Incremental_x4.fsti 2024-05-14 15:56:45.385357155 +0200 ++++ extraction-edited/Libcrux.Digest.Incremental_x4.fsti 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -module Libcrux.Digest.Incremental_x4 -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -322,7 +357,7 @@ diff -ruN extraction/Libcrux.Digest.Incremental_x4.fsti extraction-edited/Libcru -open FStar.Mul - -/// Incremental state --val t_Shake128StateX4:Type +-val t_Shake128StateX4:Type0 - -/// Absorb up to 4 blocks. -/// The `input` must be of length 1 to 4. @@ -347,44 +382,19 @@ diff -ruN extraction/Libcrux.Digest.Incremental_x4.fsti extraction-edited/Libcru - : Prims.Pure (t_Shake128StateX4 & t_Array (t_Array u8 v_N) v_M) - Prims.l_True - (fun _ -> Prims.l_True) -diff -ruN extraction/Libcrux.Digest.fsti extraction-edited/Libcrux.Digest.fsti ---- extraction/Libcrux.Digest.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Digest.fsti 2024-05-07 18:38:45 -@@ -3,13 +3,29 @@ - open Core - open FStar.Mul - -+val shake128x4_256_ (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) -+ : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) -+ Prims.l_True -+ (fun _ -> Prims.l_True) -+ - val sha3_256_ (payload: t_Slice u8) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) - - val sha3_512_ (payload: t_Slice u8) - : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) - --/// SHAKE 256 --/// The caller must define the size of the output in the return type. -+val shake128 (v_LEN: usize) (data: t_Slice u8) -+ : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) -+ - val shake256 (v_LEN: usize) (data: t_Slice u8) - : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) +diff -ruN extraction/Libcrux.Kem.fst extraction-edited/Libcrux.Kem.fst +--- extraction/Libcrux.Kem.fst 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-edited/Libcrux.Kem.fst 2024-05-14 15:56:45.425356499 +0200 +@@ -0,0 +1,6 @@ ++module Libcrux.Kem ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++open Core ++open FStar.Mul + -+val shake128x4_portable (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) -+ : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) -+ Prims.l_True -+ (fun _ -> Prims.l_True) + -+val shake128x4 (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) -+ : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) -+ Prims.l_True -+ (fun _ -> Prims.l_True) diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fst extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst ---- extraction/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-07 18:38:45 +--- extraction/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-14 15:56:45.390357073 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-14 15:56:45.434356351 +0200 @@ -1,81 +1,364 @@ module Libcrux.Kem.Kyber.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -630,18 +640,18 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fst extraction-edited/Libcrux. + }; + res +#pop-options - --let montgomery_multiply_fe_by_fer (fe fer: i32) = montgomery_reduce (fe *! fer <: i32) ++ +let montgomery_multiply_sfe_by_fer fe fer = + montgomery_reduce (mul_i32_b fe fer) +-let montgomery_multiply_fe_by_fer (fe fer: i32) = montgomery_reduce (fe *! fer <: i32) + -let to_standard_domain (mfe: i32) = - montgomery_reduce (mfe *! v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS <: i32) - --let to_unsigned_representative (fe: i32) = +let to_standard_domain mfe = + montgomery_reduce (mul_i32_b mfe (v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS <: i32_b 1353)) -+ + +-let to_unsigned_representative (fe: i32) = +let to_unsigned_representative fe = let _:Prims.unit = () <: Prims.unit in - cast (fe +! (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS &. (fe >>! 31l <: i32) <: i32) <: i32) @@ -661,8 +671,7 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fst extraction-edited/Libcrux. + assert (v fe < 0 ==> v res == v fe + 3329); + assert (v fe >= 0 ==> v res == v fe); + res <: int_t_d u16_inttype 12 - --let add_to_ring_element (v_K: usize) (lhs rhs: t_PolynomialRingElement) = ++ +let derefine_poly_b #b x = + let r = createi (sz 256) (fun i -> (x.f_coefficients.[i] <: i32)) in + {f_coefficients = r} @@ -674,7 +683,8 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fst extraction-edited/Libcrux. +let derefine_matrix_b #v_K #b x = + let r = createi v_K (fun i -> derefine_vector_b #v_K #b x.[i]) in + r -+ + +-let add_to_ring_element (v_K: usize) (lhs rhs: t_PolynomialRingElement) = +let cast_poly_b #b1 #b2 x = + let r = createi (sz 256) (fun i -> (x.f_coefficients.[i] <: i32_b b2)) in + let res = {f_coefficients = r} in @@ -790,8 +800,8 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fst extraction-edited/Libcrux. + + diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti ---- extraction/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-07 18:38:45 +--- extraction/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-14 15:56:45.378357270 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-14 15:56:45.458355957 +0200 @@ -3,175 +3,257 @@ open Core open FStar.Mul @@ -820,13 +830,13 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux -/// If 'x' denotes a value of type `fe`, values having this type hold a -/// representative y ≡ x·MONTGOMERY_R (mod FIELD_MODULUS). -/// We use 'fer' as a shorthand for this type. - unfold ++unfold +let t_FieldElement_b b = i32_b b + +unfold +let wfFieldElement = t_FieldElement_b 3328 + -+unfold + unfold let t_FieldElementTimesMontgomeryR = i32 -/// If 'x' denotes a value of type `fe`, values having this type hold a @@ -853,10 +863,7 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux -let v_MONTGOMERY_R: i32 = 1l <= 0 /\ v x < 3329 /\ (v x * v v_MONTGOMERY_R) % 3329 == 1 /\ x = 169l} + +let int_to_spec_fe (m:int) : Spec.Kyber.field_element = @@ -865,7 +872,10 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux + if m_v < 0 then + m_v + v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS + else m_v -+ + +-val get_n_least_significant_bits (n: u8) (value: u32) +- : Prims.Pure u32 +- (requires n =. 4uy || n =. 5uy || n =. 10uy || n =. 11uy || n =. v_MONTGOMERY_SHIFT) +let wf_fe_to_spec_fe (m: wfFieldElement): Spec.Kyber.field_element = + if v m < 0 + then v m + v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS @@ -952,8 +962,7 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux - <: - i32) && - result <=. ((3l *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) /! 2l <: i32)) -+ montgomery_post value result) - +- -/// If `fe` is some field element 'x' of the Kyber field and `fer` is congruent to -/// `y · MONTGOMERY_R`, this procedure outputs a value that is congruent to -/// `x · y`, as follows: @@ -962,7 +971,7 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux -/// `x · y · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x · y (mod FIELD_MODULUS)`. -val montgomery_multiply_fe_by_fer (fe fer: i32) - : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) - +- -/// If x is some field element of the Kyber field and `mfe` is congruent to -/// x · MONTGOMERY_R^{-1}, this procedure outputs a value that is congruent to -/// `x`, as follows: @@ -971,13 +980,7 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux -/// `montgomery_reduce` takes the value `x · MONTGOMERY_R` and outputs a representative -/// `x · MONTGOMERY_R * MONTGOMERY_R^{-1} ≡ x (mod FIELD_MODULUS)` -val to_standard_domain (mfe: i32) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) -+val montgomery_multiply_sfe_by_fer #b1 #b2 (fe:i32_b b1) (fer: i32_b b2) -+ : Pure (i32_b (nat_div_ceil (b1 * b2) (v v_MONTGOMERY_R) + 1665)) -+ (requires (b1 * b2 < pow2_31)) -+ (ensures (fun result -> -+ montgomery_post (mul_i32_b fe fer) (result))) -+ - +- -/// Given a field element `fe` such that -FIELD_MODULUS ≤ fe < FIELD_MODULUS, -/// output `o` such that: -/// - `o` is congruent to `fe` @@ -987,6 +990,16 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux - (requires - fe >=. (Core.Ops.Arith.Neg.neg Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) && - fe <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS) ++ montgomery_post value result) ++ ++ ++val montgomery_multiply_sfe_by_fer #b1 #b2 (fe:i32_b b1) (fer: i32_b b2) ++ : Pure (i32_b (nat_div_ceil (b1 * b2) (v v_MONTGOMERY_R) + 1665)) ++ (requires (b1 * b2 < pow2_31)) ++ (ensures (fun result -> ++ montgomery_post (mul_i32_b fe fer) (result))) ++ ++ +val to_standard_domain #b (mfe: i32_b b) + : Pure (i32_b (nat_div_ceil (b * 1353) (v v_MONTGOMERY_R) + 1665)) + (requires (b * 1353 < pow2_31)) @@ -1006,59 +1019,9 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux -type t_PolynomialRingElement = { f_coefficients:t_Array i32 (sz 256) } +type t_PolynomialRingElement = { f_coefficients:t_Array (t_FieldElement) (sz 256) } - --let impl__PolynomialRingElement__ZERO: t_PolynomialRingElement = -- { f_coefficients = Rust_primitives.Hax.repeat 0l (sz 256) } <: t_PolynomialRingElement ++ +type t_PolynomialRingElement_b b = { f_coefficients:t_Array (i32_b b) (sz 256) } - --/// Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise --/// sum of their constituent coefficients. --val add_to_ring_element (v_K: usize) (lhs rhs: t_PolynomialRingElement) -- : Prims.Pure t_PolynomialRingElement -- (requires -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- ((Core.Num.impl__i32__abs (lhs.f_coefficients.[ i ] <: i32) <: i32) <=. -- (((cast (v_K <: usize) <: i32) -! 1l <: i32) *! -- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- i32) -- <: -- bool) && -- ((Core.Num.impl__i32__abs (rhs.f_coefficients.[ i ] <: i32) <: i32) <=. -- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- bool)) -- <: -- bool)) -- (ensures -- fun result -> -- let result:t_PolynomialRingElement = result in -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize result.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (result.f_coefficients.[ i ] <: i32) <: i32) <=. -- ((cast (v_K <: usize) <: i32) *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- i32) -- <: -- bool) -- <: -- bool)) ++ +type wfPolynomialRingElement = t_PolynomialRingElement_b (v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS - 1) + +val derefine_poly_b (#b1:nat) (x:t_PolynomialRingElement_b b1): @@ -1181,11 +1144,61 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-edited/Libcrux + (forall i. v result.f_coefficients.[i] == v lhs.f_coefficients.[i] + v rhs.f_coefficients.[i])) + + -+ -+ + +-let impl__PolynomialRingElement__ZERO: t_PolynomialRingElement = +- { f_coefficients = Rust_primitives.Hax.repeat 0l (sz 256) } <: t_PolynomialRingElement + +-/// Given two polynomial ring elements `lhs` and `rhs`, compute the pointwise +-/// sum of their constituent coefficients. +-val add_to_ring_element (v_K: usize) (lhs rhs: t_PolynomialRingElement) +- : Prims.Pure t_PolynomialRingElement +- (requires +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- ((Core.Num.impl__i32__abs (lhs.f_coefficients.[ i ] <: i32) <: i32) <=. +- (((cast (v_K <: usize) <: i32) -! 1l <: i32) *! +- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- i32) +- <: +- bool) && +- ((Core.Num.impl__i32__abs (rhs.f_coefficients.[ i ] <: i32) <: i32) <=. +- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- bool)) +- <: +- bool)) +- (ensures +- fun result -> +- let result:t_PolynomialRingElement = result in +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize result.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (result.f_coefficients.[ i ] <: i32) <: i32) <=. +- ((cast (v_K <: usize) <: i32) *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- i32) +- <: +- bool) +- <: +- bool)) diff -ruN extraction/Libcrux.Kem.Kyber.Compress.fst extraction-edited/Libcrux.Kem.Kyber.Compress.fst ---- extraction/Libcrux.Kem.Kyber.Compress.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Compress.fst 2024-05-07 18:38:45 +--- extraction/Libcrux.Kem.Kyber.Compress.fst 2024-05-14 15:56:45.404356843 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Compress.fst 2024-05-14 15:56:45.448356122 +0200 @@ -1,39 +1,79 @@ module Libcrux.Kem.Kyber.Compress -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -1240,11 +1253,10 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Compress.fst extraction-edited/Libcrux.Ke + assert (v fe > 2496 ==> r1 = 0s); + assert (v res = v r1); + res - --let decompress_ciphertext_coefficient (coefficient_bits: u8) (fe: i32) = ++ +let compress_ciphertext_coefficient coefficient_bits fe = - let _:Prims.unit = () <: Prims.unit in - let _:Prims.unit = () <: Prims.unit in ++ let _:Prims.unit = () <: Prims.unit in ++ let _:Prims.unit = () <: Prims.unit in + let compressed:u32 = (cast (fe <: u16) <: u32) < v result >= 0 /\ v result < 3329) -diff -ruN extraction/Libcrux.Kem.Kyber.Constant_time_ops.fst extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst ---- extraction/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-07 18:38:45 -@@ -4,56 +4,163 @@ +diff -ruN extraction/Libcrux.Kem.Kyber.Constants.fsti extraction-edited/Libcrux.Kem.Kyber.Constants.fsti +--- extraction/Libcrux.Kem.Kyber.Constants.fsti 2024-05-14 15:56:45.401356893 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Constants.fsti 2024-05-14 15:56:45.445356171 +0200 +@@ -3,24 +3,20 @@ + open Core open FStar.Mul - let is_non_zero (value: u8) = -+ let orig_value = value in - let value:u16 = cast (value <: u8) <: u16 in -- let result:u16 = -- ((value |. (Core.Num.impl__u16__wrapping_add (~.value <: u16) 1us <: u16) <: u16) >>! 8l <: u16) &. -- 1us +-/// Each field element needs floor(log_2(FIELD_MODULUS)) + 1 = 12 bits to represent + let v_BITS_PER_COEFFICIENT: usize = sz 12 + +-/// Coefficients per ring element + let v_COEFFICIENTS_IN_RING_ELEMENT: usize = sz 256 + +-/// Bits required per (uncompressed) ring element + let v_BITS_PER_RING_ELEMENT: usize = v_COEFFICIENTS_IN_RING_ELEMENT *! sz 12 + +-/// Bytes required per (uncompressed) ring element + let v_BYTES_PER_RING_ELEMENT: usize = v_BITS_PER_RING_ELEMENT /! sz 8 + + let v_CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = sz 32 + +-/// Field modulus: 3329 + let v_FIELD_MODULUS: i32 = 3329l + + let v_H_DIGEST_SIZE: usize = sz 32 + +-/// PKE message size ++let v_REJECTION_SAMPLING_SEED_SIZE: usize = sz 168 *! sz 5 ++ + let v_SHARED_SECRET_SIZE: usize = sz 32 +diff -ruN extraction/Libcrux.Kem.Kyber.Constant_time_ops.fst extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst +--- extraction/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-14 15:56:45.410356745 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-14 15:56:45.441356237 +0200 +@@ -4,56 +4,163 @@ + open FStar.Mul + + let is_non_zero (value: u8) = ++ let orig_value = value in + let value:u16 = cast (value <: u8) <: u16 in +- let result:u16 = +- ((value |. (Core.Num.impl__u16__wrapping_add (~.value <: u16) 1us <: u16) <: u16) >>! 8l <: u16) &. +- 1us - in - cast (result <: u16) <: u8 + let result:u8 = cast ((Core.Num.impl__u16__wrapping_add (~.value <: u16) 1us <: u16) >>! 8l <: u16) in @@ -1573,8 +1616,8 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Constant_time_ops.fst extraction-edited/L + ) +#pop-options diff -ruN extraction/Libcrux.Kem.Kyber.Constant_time_ops.fsti extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti ---- extraction/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-07 18:38:45 +--- extraction/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-14 15:56:45.411356728 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-14 15:56:45.447356138 +0200 @@ -3,7 +3,6 @@ open Core open FStar.Mul @@ -1621,1092 +1664,630 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Constant_time_ops.fsti extraction-edited/ - result =. rhs <: bool)) + Hax_lib.implies (selector =. 0uy <: bool) (fun _ -> result =. lhs <: bool) && + Hax_lib.implies (selector <>. 0uy <: bool) (fun _ -> result =. rhs <: bool)) -diff -ruN extraction/Libcrux.Kem.Kyber.Constants.fsti extraction-edited/Libcrux.Kem.Kyber.Constants.fsti ---- extraction/Libcrux.Kem.Kyber.Constants.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Constants.fsti 2024-05-07 18:38:45 -@@ -3,24 +3,20 @@ +diff -ruN extraction/Libcrux.Kem.Kyber.fst extraction-edited/Libcrux.Kem.Kyber.fst +--- extraction/Libcrux.Kem.Kyber.fst 2024-05-14 15:56:45.402356876 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.fst 2024-05-14 15:56:45.465355843 +0200 +@@ -1,12 +1,29 @@ + module Libcrux.Kem.Kyber +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" open Core open FStar.Mul --/// Each field element needs floor(log_2(FIELD_MODULUS)) + 1 = 12 bits to represent - let v_BITS_PER_COEFFICIENT: usize = sz 12 - --/// Coefficients per ring element - let v_COEFFICIENTS_IN_RING_ELEMENT: usize = sz 256 - --/// Bits required per (uncompressed) ring element - let v_BITS_PER_RING_ELEMENT: usize = v_COEFFICIENTS_IN_RING_ELEMENT *! sz 12 - --/// Bytes required per (uncompressed) ring element - let v_BYTES_PER_RING_ELEMENT: usize = v_BITS_PER_RING_ELEMENT /! sz 8 - - let v_CPA_PKE_KEY_GENERATION_SEED_SIZE: usize = sz 32 - --/// Field modulus: 3329 - let v_FIELD_MODULUS: i32 = 3329l - - let v_H_DIGEST_SIZE: usize = sz 32 - --/// PKE message size -+let v_REJECTION_SAMPLING_SEED_SIZE: usize = sz 168 *! sz 5 +-let serialize_kem_secret_key ++let update_at_range_lemma #n ++ (s: t_Slice 't) ++ (i: Core.Ops.Range.t_Range (int_t n) {(Core.Ops.Range.impl_index_range_slice 't n).f_index_pre s i}) ++ (x: t_Slice 't) ++ : Lemma ++ (requires (Seq.length x == v i.f_end - v i.f_start)) ++ (ensures ( ++ let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in ++ let len = v i.f_start in ++ forall (i: nat). i < len ==> Seq.index s i == Seq.index s' i ++ )) ++ [SMTPat (Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x)] ++ = let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in ++ let len = v i.f_start in ++ introduce forall (i:nat {i < len}). Seq.index s i == Seq.index s' i ++ with (assert ( Seq.index (Seq.slice s 0 len) i == Seq.index s i ++ /\ Seq.index (Seq.slice s' 0 len) i == Seq.index s' i )) + - let v_SHARED_SECRET_SIZE: usize = sz 32 -diff -ruN extraction/Libcrux.Kem.Kyber.Hash_functions.fst extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst ---- extraction/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-07 18:38:45 -@@ -3,129 +3,114 @@ - open Core - open FStar.Mul - --let v_G (input: t_Slice u8) = Libcrux.Digest.sha3_512_ input -+let v_G (input: t_Slice u8) = -+ let res = Libcrux.Digest.sha3_512_ input in -+ admit(); // We assume that sha3_512 correctly implements G -+ res - --let v_H (input: t_Slice u8) = Libcrux.Digest.sha3_256_ input -+let v_H (input: t_Slice u8) = -+ let res = Libcrux.Digest.sha3_256_ input in -+ admit(); // We assume that sha3_512 correctly implements H -+ res - --let v_PRF (v_LEN: usize) (input: t_Slice u8) = Libcrux.Digest.shake256 v_LEN input -+let v_PRF (v_LEN: usize) (input: t_Slice u8) = -+ let res = Libcrux.Digest.shake256 v_LEN input in -+ admit(); // We assume that sha3_512 correctly implements H -+ res - --let absorb (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) = -- let _:Prims.unit = -- if true -+let v_XOFx4 v_K (input: t_Array (t_Array u8 (sz 34)) v_K) = -+ assert (v v_K >= 2); -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 840) <: t_Array u8 (sz 840)) v_K -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ if ~.(Libcrux_platform.Platform.simd256_support () <: bool) - then -- let _:Prims.unit = -- if ~.((v_K =. sz 2 <: bool) || (v_K =. sz 3 <: bool) || (v_K =. sz 4 <: bool)) -- then -- Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: K == 2 || K == 3 || K == 4" -- -+ Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ Core.Ops.Range.f_start = sz 0; -+ Core.Ops.Range.f_end = v_K -+ } ++let serialize_kem_secret_key #p + (v_SERIALIZED_KEY_LEN: usize) +- (private_key public_key implicit_rejection_value: t_Slice u8) +- = ++ (private_key public_key implicit_rejection_value: t_Slice u8) = + let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.repeat 0uy v_SERIALIZED_KEY_LEN in + let pointer:usize = sz 0 in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = +@@ -55,6 +72,8 @@ + t_Slice u8) + in + let pointer:usize = pointer +! (Core.Slice.impl__len public_key <: usize) in ++ let h_public_key = (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) ++ <: t_Slice u8) in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + ({ +@@ -70,16 +89,7 @@ + pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE <: usize + } <: -- Rust_primitives.Hax.t_Never) -- in -- () -- in -- let state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = -- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__new () -- in -- let (data: t_Array (t_Slice u8) v_K):t_Array (t_Slice u8) v_K = -- Rust_primitives.Hax.repeat (Rust_primitives.unsize (let list = [0uy] in -- FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); -- Rust_primitives.Hax.array_of_list 1 list) -- <: -- t_Slice u8) -- v_K -- in -- let data:t_Array (t_Slice u8) v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = v_K -- } +- Core.Ops.Range.t_Range usize ] - <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- data -- (fun data i -> -- let data:t_Array (t_Slice u8) v_K = data in -- let i:usize = i in -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize data -- i -- (Rust_primitives.unsize (input.[ i ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ Core.Ops.Range.t_Range usize) - <: -- t_Array (t_Slice u8) v_K) -- in -- let state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = -- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__absorb_final v_K state data -- in -- state -- --let free_state (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = -- let _:Prims.unit = Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__free_memory xof_state in -- () -- --let squeeze_block (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = -- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & -- t_Array (t_Array u8 (sz 168)) v_K) = -- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__squeeze_blocks (sz 168) v_K xof_state -- in -- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in -- let (output: t_Array (t_Array u8 (sz 168)) v_K):t_Array (t_Array u8 (sz 168)) v_K = out1 in -- let out:t_Array (t_Array u8 (sz 168)) v_K = -- Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) v_K -- in -- let out:t_Array (t_Array u8 (sz 168)) v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = v_K -- } -+ Core.Ops.Range.t_Range usize) -+ out -+ (fun out i -> -+ let out:t_Array (t_Array u8 (sz 840)) v_K = out in -+ let i:usize = i in -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -+ i -+ (Libcrux.Digest.shake128 (sz 840) -+ (Rust_primitives.unsize (input.[ i ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ <: -+ t_Array u8 (sz 840)) - <: -- Core.Ops.Range.t_Range usize) +- t_Slice u8) +- (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key +- <: +- t_Array u8 (sz 32)) +- <: +- t_Slice u8) - <: -- Core.Ops.Range.t_Range usize) -+ t_Array (t_Array u8 (sz 840)) v_K) -+ else -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ match cast (v_K <: usize) <: u8 with -+ | 2uy -> -+ let d0, d1, _, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & -+ t_Array u8 (sz 840)) = -+ Libcrux.Digest.shake128x4 (sz 840) -+ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) d0 -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) d1 -+ in -+ out -+ | 3uy -> -+ assert (v (cast v_K <: u8) = 3); -+ let d0, d1, d2, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & -+ t_Array u8 (sz 840)) = -+ Libcrux.Digest.shake128x4 (sz 840) -+ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) d0 -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) d1 -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) d2 -+ in -+ out -+ | 4uy -> -+ assert (v (cast v_K <: u8) = 4); -+ let d0, d1, d2, d3:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & -+ t_Array u8 (sz 840)) = -+ Libcrux.Digest.shake128x4 (sz 840) -+ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ (Rust_primitives.unsize (input.[ sz 3 ] <: t_Array u8 (sz 34)) <: t_Slice u8) -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) d0 -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) d1 -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) d2 -+ in -+ let out:t_Array (t_Array u8 (sz 840)) v_K = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) d3 -+ in -+ out -+ | _ -> out -+ in - out -- (fun out i -> -- let out:t_Array (t_Array u8 (sz 168)) v_K = out in -- let i:usize = i in -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -- i -- (output.[ i ] <: t_Array u8 (sz 168)) -- <: -- t_Array (t_Array u8 (sz 168)) v_K) +- t_Slice u8) ++ Core.Ops.Range.t_Range usize ]) h_public_key) in -- let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in -- xof_state, hax_temp_output -- <: -- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 168)) v_K) -- --let squeeze_three_blocks (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = -- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & -- t_Array (t_Array u8 (sz 504)) v_K) = -- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__squeeze_blocks (sz 504) v_K xof_state -- in -- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in -- let (output: t_Array (t_Array u8 (sz 504)) v_K):t_Array (t_Array u8 (sz 504)) v_K = out1 in -- let out:t_Array (t_Array u8 (sz 504)) v_K = -- Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 504) <: t_Array u8 (sz 504)) v_K -- in -- let out:t_Array (t_Array u8 (sz 504)) v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = v_K -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- out -- (fun out i -> -- let out:t_Array (t_Array u8 (sz 504)) v_K = out in -- let i:usize = i in -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -- i -- (output.[ i ] <: t_Array u8 (sz 504)) -- <: -- t_Array (t_Array u8 (sz 504)) v_K) -- in -- let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in -- xof_state, hax_temp_output -- <: -- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 504)) v_K) -+ admit(); // We assume that shake128x4 correctly implements XOFx4 -+ out -diff -ruN extraction/Libcrux.Kem.Kyber.Hash_functions.fsti extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti ---- extraction/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-07 18:38:45 -@@ -3,35 +3,17 @@ - open Core - open FStar.Mul - --let v_BLOCK_SIZE: usize = sz 168 -+val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True -+ (ensures (fun res -> res == Spec.Kyber.v_G input)) - --val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) -+val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True -+ (ensures (fun res -> res == Spec.Kyber.v_H input)) - --val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -- - val v_PRF (v_LEN: usize) (input: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) -- --let v_THREE_BLOCKS: usize = v_BLOCK_SIZE *! sz 3 -- --val absorb (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) -- : Prims.Pure Libcrux.Digest.Incremental_x4.t_Shake128StateX4 -- Prims.l_True -- (fun _ -> Prims.l_True) -- --/// Free the memory of the state. --/// **NOTE:** That this needs to be done manually for now. --val free_state (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) -- : Prims.Pure Prims.unit Prims.l_True (fun _ -> Prims.l_True) -- --val squeeze_block (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) -- : Prims.Pure -- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 168)) v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -- --val squeeze_three_blocks (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) -- : Prims.Pure -- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 504)) v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Prims.Pure (t_Array u8 v_LEN) Prims.l_True -+ (ensures (fun res -> res == Spec.Kyber.v_PRF v_LEN input)) -+ -+val v_XOFx4 (v_K: usize{v v_K >= 2 /\ v v_K <= 4}) (input: t_Array (t_Array u8 (sz 34)) v_K) -+ : Prims.Pure (t_Array (t_Array u8 (sz 840)) v_K) Prims.l_True -+ (ensures (fun res -> -+ (forall i. i < v v_K ==> Seq.index res i == Spec.Kyber.v_XOF (sz 840) (Seq.index input i)))) -diff -ruN extraction/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst ---- extraction/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-07 18:38:45 -@@ -1,5 +1,5 @@ - module Libcrux.Kem.Kyber.Ind_cpa --#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" - open Core - open FStar.Mul - -@@ -37,33 +37,37 @@ + let pointer:usize = pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = +@@ -106,14 +116,32 @@ + <: + t_Slice u8) in ++ assert (Seq.slice out 0 (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) `Seq.equal` private_key); ++ assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) ++ (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) `Seq.equal` public_key); ++ assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! ++ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) ++ (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! ++ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! ++ Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) ++ `Seq.equal` Libcrux.Kem.Kyber.Hash_functions.v_H public_key); ++ assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! ++ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! ++ Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) ++ (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! ++ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! ++ Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE +! ++ Spec.Kyber.v_SHARED_SECRET_SIZE)) ++ == implicit_rejection_value); ++ lemma_slice_append_4 out private_key public_key (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value; out --let sample_ring_element_cbd -+unfold let acc_t (v_K v_ETA:usize) = (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1)) v_K) -+unfold let inv_t v_K v_ETA = acc_t v_K v_ETA -> usize -> Type -+ -+let wfZero: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) -+ -+let etaZero (v_ETA:usize{v v_ETA >= 1 /\ v v_ETA < pow2 31}): Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA) = -+ (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #(v v_ETA) Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) -+ -+let sample_vector_cbd (#p:Spec.Kyber.params) - (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) -- (prf_input: t_Array u8 (sz 33)) -- (domain_separator: u8) +-let decapsulate ++let decapsulate #p + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) - = -- let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -+ (prf_input: t_Array u8 (sz 33)) domain_separator = -+ let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = -+ Rust_primitives.Hax.repeat (etaZero (sz (pow2 (v v_ETA2) - 1))) v_K ++ (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = ++ let orig_secret_key = secret_key.f_value in + let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = + Libcrux.Kem.Kyber.Types.impl_12__split_at v_SECRET_KEY_SIZE secret_key v_CPA_SECRET_KEY_SIZE in -- let domain_separator, error_1_, prf_input:(u8 & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array u8 (sz 33)) = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ let orig_domain_separator = domain_separator in -+ [@ inline_let] -+ let inv : inv_t v_K v_ETA2 = fun (acc:acc_t v_K v_ETA2) (i:usize) -> -+ let (domain_separator,prf_input,error_1_) = acc in -+ if (i >=. sz 0 && i <=. v_K) -+ then -+ domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) -+ else true in -+ let (domain_separator, prf_input, error_1_):acc_t v_K (v_ETA2) = -+ Rust_primitives.Iterators.foldi_range #_ #(acc_t v_K (v_ETA2)) #inv { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- (domain_separator, error_1_, prf_input -- <: -- (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array u8 (sz 33)) -- ) -+ (domain_separator, prf_input, error_1_) - (fun temp_0_ i -> -- let domain_separator, error_1_, prf_input:(u8 & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array u8 (sz 33)) = -+ let domain_separator, prf_input, error_1_:acc_t v_K (v_ETA2) = - temp_0_ - in - let i:usize = i in -@@ -77,49 +81,46 @@ - Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE - (Rust_primitives.unsize prf_input <: t_Slice u8) - in -- let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize error_1_ - i -- (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA2 -+ (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA2 - (Rust_primitives.unsize prf_output <: t_Slice u8) - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) - in -- domain_separator, error_1_, prf_input -- <: -- (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array u8 (sz 33))) -+ domain_separator, prf_input, error_1_) +@@ -123,8 +151,12 @@ + let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at secret_key Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE in -- let hax_temp_output:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = error_1_ in -+ let hax_temp_output:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = error_1_ in -+ admit(); //P-F - prf_input, domain_separator, hax_temp_output - <: -- (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ (t_Array u8 (sz 33) & u8 & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA2)) v_K) - --let sample_vector_cbd_then_ntt -+#push-options "--split_queries no --z3rlimit 300" -+let sample_vector_cbd_then_ntt (#p:Spec.Kyber.params) - (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) -- (prf_input: t_Array u8 (sz 33)) -- (domain_separator: u8) -- = -- let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -+ (prf_input: t_Array u8 (sz 33)) domain_separator = -+ let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat (wfZero) v_K ++ assert (ind_cpa_secret_key == slice orig_secret_key (sz 0) v_CPA_SECRET_KEY_SIZE); ++ assert (ind_cpa_public_key == slice orig_secret_key v_CPA_SECRET_KEY_SIZE (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE)); ++ assert (ind_cpa_public_key_hash == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE) (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)); ++ assert (implicit_rejection_value == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) (length orig_secret_key)); + let decrypted:t_Array u8 (sz 32) = +- Libcrux.Kem.Kyber.Ind_cpa.decrypt v_K ++ Libcrux.Kem.Kyber.Ind_cpa.decrypt #p v_K + v_CIPHERTEXT_SIZE + v_C1_SIZE + v_VECTOR_U_COMPRESSION_FACTOR +@@ -152,6 +184,9 @@ + <: + t_Slice u8) in -- let domain_separator, prf_input, re_as_ntt:(u8 & t_Array u8 (sz 33) & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ let orig_domain_separator = domain_separator in -+ [@ inline_let] -+ let inv: (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K) -> usize -> Type = fun acc i -> -+ let (domain_separator,prf_input,re_as_ntt) = acc in -+ if (i >=. sz 0 && i <=. v_K) -+ then -+ domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) -+ else true in -+ let (domain_separator, prf_input, re_as_ntt):(u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K)= -+ Rust_primitives.Iterators.foldi_range #_ #_ #inv { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- (domain_separator, prf_input, re_as_ntt -- <: -- (u8 & t_Array u8 (sz 33) & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- ) -+ (domain_separator, prf_input, re_as_ntt) - (fun temp_0_ i -> - let domain_separator, prf_input, re_as_ntt:(u8 & t_Array u8 (sz 33) & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = - temp_0_ - in - let i:usize = i in -@@ -133,64 +134,74 @@ - Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA_RANDOMNESS_SIZE - (Rust_primitives.unsize prf_input <: t_Slice u8) - in -- let r:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA -+ let r:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1) = -+ Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA - (Rust_primitives.unsize prf_output <: t_Slice u8) - in -- let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ let r:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b r in -+ let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re_as_ntt - i - (Libcrux.Kem.Kyber.Ntt.ntt_binomially_sampled_ring_element r - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - in - domain_separator, prf_input, re_as_ntt - <: - (u8 & t_Array u8 (sz 33) & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K)) ++ lemma_slice_append to_hash decrypted ind_cpa_public_key_hash; ++ assert (decrypted == Spec.Kyber.ind_cpa_decrypt p ind_cpa_secret_key ciphertext.f_value); ++ assert (to_hash == concat decrypted ind_cpa_public_key_hash); + let hashed:t_Array u8 (sz 64) = + Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) in -+ admit(); //P-F - re_as_ntt, domain_separator - <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & u8) -+ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & u8) +@@ -159,6 +194,10 @@ + Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) + Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + in ++ assert ((shared_secret,pseudorandomness) == split hashed Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE); ++ assert (length implicit_rejection_value = v_SECRET_KEY_SIZE -! v_CPA_SECRET_KEY_SIZE -! v_PUBLIC_KEY_SIZE -! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE); ++ assert (length implicit_rejection_value = Spec.Kyber.v_SHARED_SECRET_SIZE); ++ assert (Spec.Kyber.v_SHARED_SECRET_SIZE <=. Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p); + let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = + Libcrux.Kem.Kyber.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE +@@ -180,11 +219,14 @@ + <: + t_Slice u8) + in ++ lemma_slice_append to_hash implicit_rejection_value ciphertext.f_value; + let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = + Libcrux.Kem.Kyber.Hash_functions.v_PRF (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) + in ++ assert (implicit_rejection_shared_secret == Spec.Kyber.v_J to_hash); ++ assert (Seq.length ind_cpa_public_key == v v_PUBLIC_KEY_SIZE); + let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE ++ Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE ind_cpa_public_key decrypted + pseudorandomness +@@ -194,16 +236,18 @@ + (Core.Convert.f_as_ref ciphertext <: t_Slice u8) + (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) + in ++ let res = + Libcrux.Kem.Kyber.Constant_time_ops.select_shared_secret_in_constant_time shared_secret + (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) + selector ++ in ++ res --let compress_then_serialize_u -- (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) -- (input: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +-let encapsulate ++let encapsulate #p + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +- (randomness: t_Array u8 (sz 32)) - = ++ (randomness: t_Array u8 (sz 32)) = + let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = + Libcrux.Kem.Kyber.Ind_cpa.into_padded_array (sz 64) + (Rust_primitives.unsize randomness <: t_Slice u8) +@@ -234,6 +278,10 @@ + <: + t_Slice u8) + in ++ assert (Seq.slice to_hash 0 (v Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) == randomness); ++ lemma_slice_append to_hash randomness (Spec.Kyber.v_H public_key.f_value); ++ assert (to_hash == concat randomness (Spec.Kyber.v_H public_key.f_value)); + -+let compress_then_serialize_u #p v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN input = - let out:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in -+ let orig_out = out in -+ let acc_t = t_Array u8 v_OUT_LEN in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> True in - let out:t_Array u8 v_OUT_LEN = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Iter.Traits.Collect.f_into_iter input -- <: -- Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -+ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #acc_t #inv -+ input - out - (fun out temp_1_ -> - let out:t_Array u8 v_OUT_LEN = out in -- let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = temp_1_ in -+ let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = temp_1_ in -+ assert (i <. v_K); -+ assert (v i + 1 <= v v_K); -+ assert (v i * (v v_OUT_LEN / v v_K) < v v_OUT_LEN); -+ assert (((v i + 1) * (v v_OUT_LEN / v v_K)) <= v v_OUT_LEN); -+ assert (v_OUT_LEN /! v_K == Spec.Kyber.v_C1_BLOCK_SIZE p); -+ assert (range (v i * v (Spec.Kyber.v_C1_BLOCK_SIZE p)) usize_inttype); -+ assert (range ((v i + 1) * v (Spec.Kyber.v_C1_BLOCK_SIZE p)) usize_inttype); -+ assert ((Core.Ops.Range.impl_index_range_slice u8 usize_inttype).f_index_pre out -+ { -+ Core.Ops.Range.f_start = i *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize; -+ Core.Ops.Range.f_end -+ = -+ (i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize -+ }); -+ assert (((i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p) -! (i *! Spec.Kyber.v_C1_BLOCK_SIZE p) == Spec.Kyber.v_C1_BLOCK_SIZE p); - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out - ({ -- Core.Ops.Range.f_start = i *! (v_OUT_LEN /! v_K <: usize) <: usize; -- Core.Ops.Range.f_end = (i +! sz 1 <: usize) *! (v_OUT_LEN /! v_K <: usize) <: usize -+ Core.Ops.Range.f_start = i *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize; -+ Core.Ops.Range.f_end = (i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize - } - <: - Core.Ops.Range.t_Range usize) - (Core.Slice.impl__copy_from_slice (out.[ { -- Core.Ops.Range.f_start = i *! (v_OUT_LEN /! v_K <: usize) <: usize; -+ Core.Ops.Range.f_start = i *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize; - Core.Ops.Range.f_end - = -- (i +! sz 1 <: usize) *! (v_OUT_LEN /! v_K <: usize) <: usize -- } -- <: -- Core.Ops.Range.t_Range usize ] -+ (i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize -+ } ] - <: - t_Slice u8) -- (Rust_primitives.unsize (Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_u -+ (Rust_primitives.unsize (Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_u #p - v_COMPRESSION_FACTOR - v_BLOCK_LEN - re -@@ -203,153 +214,168 @@ - <: - t_Array u8 v_OUT_LEN) + let hashed:t_Array u8 (sz 64) = + Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) in -+ admit();//P-F - out - --let encrypt_unpacked -- (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: -- usize) -- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- (a_transpose: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- (message: t_Array u8 (sz 32)) -- (randomness: t_Slice u8) -- = -- let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = into_padded_array (sz 33) randomness in -- let r_as_ntt, domain_separator:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- u8) = -- sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy -+#push-options "--split_queries always" -+let deserialize_then_decompress_u (#p:Spec.Kyber.params) -+ (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR: usize) -+ (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = -+ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat wfZero v_K +@@ -242,7 +290,7 @@ + Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE in -- let tmp0, tmp1, out:(t_Array u8 (sz 33) & u8 & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -- sample_ring_element_cbd v_K v_ETA2_RANDOMNESS_SIZE v_ETA2 prf_input domain_separator -- in -- let prf_input:t_Array u8 (sz 33) = tmp0 in -- let domain_separator:u8 = tmp1 in -- let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = out in -- let prf_input:t_Array u8 (sz 33) = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_input (sz 32) domain_separator -- in -- let (prf_output: t_Array u8 v_ETA2_RANDOMNESS_SIZE):t_Array u8 v_ETA2_RANDOMNESS_SIZE = -- Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE -- (Rust_primitives.unsize prf_input <: t_Slice u8) -- in -- let error_2_:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA2 -- (Rust_primitives.unsize prf_output <: t_Slice u8) + let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE ++ Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN + v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE + (Rust_primitives.unsize (Libcrux.Kem.Kyber.Types.impl_18__as_slice v_PUBLIC_KEY_SIZE +@@ -252,32 +300,29 @@ + <: + t_Slice u8) randomness pseudorandomness + in +- let shared_secret_array:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in +- let shared_secret_array:t_Array u8 (sz 32) = +- Core.Slice.impl__copy_from_slice shared_secret_array shared_secret - in -- let u:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Libcrux.Kem.Kyber.Matrix.compute_vector_u v_K a_transpose r_as_ntt error_1_ +- Core.Convert.f_into ciphertext, shared_secret_array ++ Core.Convert.f_into ciphertext, ++ Core.Result.impl__unwrap (Core.Convert.f_try_into shared_secret ++ <: ++ Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError) + <: + (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + +-let validate_public_key ++#push-options "--z3rlimit 100" ++let validate_public_key #p + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) + = +- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Libcrux.Kem.Kyber.Serialize.deserialize_ring_elements_reduced v_PUBLIC_KEY_SIZE +- v_K ++ let pk:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Libcrux.Kem.Kyber.Ind_cpa.deserialize_public_key #p v_K + (public_key.[ { Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } + <: +- Core.Ops.Range.t_RangeTo usize ] +- <: +- t_Slice u8) ++ Core.Ops.Range.t_RangeTo usize ]) + in + let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.serialize_public_key v_K ++ Libcrux.Kem.Kyber.Ind_cpa.serialize_public_key #p v_K + v_RANKED_BYTES_PER_RING_ELEMENT + v_PUBLIC_KEY_SIZE +- deserialized_pk ++ pk + (public_key.[ { Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } + <: + Core.Ops.Range.t_RangeFrom usize ] +@@ -285,109 +330,12 @@ + t_Slice u8) + in + public_key =. public_key_serialized ++#pop-options + +-let decapsulate_unpacked +- (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: +- usize) +- (state: t_MlKemState v_K) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) +- = +- let (secret_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K):t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- state.f_secret_as_ntt - in -- let message_as_ring_element:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_message message +- let (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K):t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- state.f_t_as_ntt - in -- let v:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Matrix.compute_ring_element_v v_K -- tt_as_ntt -- r_as_ntt -- error_2_ -- message_as_ring_element +- let (a_transpose: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K):t_Array +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- state.f_a_transpose - in -- let c1:t_Array u8 v_C1_LEN = -- compress_then_serialize_u v_K v_C1_LEN v_U_COMPRESSION_FACTOR v_BLOCK_LEN u +- let (implicit_rejection_value: t_Slice u8):t_Slice u8 = Rust_primitives.unsize state.f_rej in +- let (ind_cpa_public_key_hash: t_Slice u8):t_Slice u8 = +- Rust_primitives.unsize state.f_ind_cpa_public_key_hash - in -- let c2:t_Array u8 v_C2_LEN = -- Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_v v_V_COMPRESSION_FACTOR -- v_C2_LEN -- v +- let decrypted:t_Array u8 (sz 32) = +- Libcrux.Kem.Kyber.Ind_cpa.decrypt_unpacked v_K +- v_CIPHERTEXT_SIZE +- v_C1_SIZE +- v_VECTOR_U_COMPRESSION_FACTOR +- v_VECTOR_V_COMPRESSION_FACTOR +- secret_as_ntt +- ciphertext.Libcrux.Kem.Kyber.Types.f_value - in -- let (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE):t_Array u8 v_CIPHERTEXT_SIZE = -- into_padded_array v_CIPHERTEXT_SIZE (Rust_primitives.unsize c1 <: t_Slice u8) +- let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = +- Libcrux.Kem.Kyber.Ind_cpa.into_padded_array (sz 64) +- (Rust_primitives.unsize decrypted <: t_Slice u8) - in -- let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from ciphertext -- ({ Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize) -- (Core.Slice.impl__copy_from_slice (ciphertext.[ { Core.Ops.Range.f_start = v_C1_LEN } +- let to_hash:t_Array u8 (sz 64) = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from to_hash +- ({ Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE } +- <: +- Core.Ops.Range.t_RangeFrom usize) +- (Core.Slice.impl__copy_from_slice (to_hash.[ { +- Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE +- } - <: - Core.Ops.Range.t_RangeFrom usize ] - <: - t_Slice u8) -- (Core.Array.impl_23__as_slice v_C2_LEN c2 <: t_Slice u8) +- ind_cpa_public_key_hash - <: - t_Slice u8) - in -- ciphertext -- --let deserialize_then_decompress_u -- (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) -- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) -- = -- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- let hashed:t_Array u8 (sz 64) = +- Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) - in -- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize ciphertext <: t_Slice u8) -- ((Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! -+ let acc_t1 = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in -+ [@ inline_let] -+ let inv = fun (acc:acc_t1) (i:usize) -> True in -+ let sl : t_Slice u8 = ciphertext.[ -+ { Core.Ops.Range.f_end = v_VECTOR_U_ENCODED_SIZE } <: Core.Ops.Range.t_RangeTo usize ] in -+ assert (length sl == v_VECTOR_U_ENCODED_SIZE); -+ let chunk_len = ((Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! - v_U_COMPRESSION_FACTOR - <: - usize) /! - sz 8 - <: -- usize) -- <: -- Core.Slice.Iter.t_ChunksExact u8) +- let shared_secret, pseudorandomness:(t_Slice u8 & t_Slice u8) = +- Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) +- Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE +- in +- let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 +- v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE +- implicit_rejection_value +- in +- let to_hash:t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from to_hash +- ({ Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE } +- <: +- Core.Ops.Range.t_RangeFrom usize) +- (Core.Slice.impl__copy_from_slice (to_hash.[ { +- Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE +- } +- <: +- Core.Ops.Range.t_RangeFrom usize ] - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- t_Slice u8) +- (Core.Convert.f_as_ref ciphertext <: t_Slice u8) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ usize) in -+ FStar.Math.Lemmas.cancel_mul_mod (v p.v_RANK) (v (Spec.Kyber.v_C1_BLOCK_SIZE p)) ; -+ assert (v chunk_len == v (Spec.Kyber.v_C1_BLOCK_SIZE p)); -+ assert (Seq.length sl % v (Spec.Kyber.v_C1_BLOCK_SIZE p) = 0); -+ assert (Seq.length sl == v (Spec.Kyber.v_C1_SIZE p)); -+ assert (Seq.length sl / v (Spec.Kyber.v_C1_BLOCK_SIZE p) == v v_K); -+ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t1 #inv -+ sl -+ chunk_len - u_as_ntt - (fun u_as_ntt temp_1_ -> -- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - u_as_ntt - in -- let i, u_bytes:(usize & t_Slice u8) = temp_1_ in -- let u:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let i, u_bytes:(usize & t_Array u8 chunk_len) = temp_1_ in -+ let u:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_ring_element_u v_U_COMPRESSION_FACTOR - u_bytes - in -- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ assert (v i < v v_K); -+ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize u_as_ntt - i - (Libcrux.Kem.Kyber.Ntt.ntt_vector_u v_U_COMPRESSION_FACTOR u - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - in - u_as_ntt) +- t_Slice u8) +- in +- let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = +- Libcrux.Kem.Kyber.Hash_functions.v_PRF (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) +- in +- let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.encrypt_unpacked v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE +- v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR +- v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE tt_as_ntt +- a_transpose decrypted pseudorandomness +- in +- let selector:u8 = +- Libcrux.Kem.Kyber.Constant_time_ops.compare_ciphertexts_in_constant_time v_CIPHERTEXT_SIZE +- (Core.Convert.f_as_ref ciphertext <: t_Slice u8) +- (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) +- in +- Libcrux.Kem.Kyber.Constant_time_ops.select_shared_secret_in_constant_time shared_secret +- (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) +- selector +- +-let generate_keypair ++let generate_keypair #p + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) +- (randomness: t_Array u8 (sz 64)) +- = ++ (randomness: t_Array u8 (sz 64)) = + let ind_cpa_keypair_randomness:t_Slice u8 = + randomness.[ { + Core.Ops.Range.f_start = sz 0; +@@ -405,7 +353,7 @@ in -+ admit(); //P-F - u_as_ntt -+#pop-options - --let decrypt_unpacked -+#push-options "--z3rlimit 200" -+let deserialize_public_key (#p:Spec.Kyber.params) -+ (v_K: usize) (public_key: t_Slice u8) = -+ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat wfZero v_K -+ in -+ let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> True in -+ let chunk_len = Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT in -+ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv -+ public_key -+ chunk_len -+ tt_as_ntt -+ (fun tt_as_ntt temp_1_ -> -+ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ tt_as_ntt -+ in -+ let i, tt_as_ntt_bytes:(usize & t_Array u8 chunk_len) = temp_1_ in -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize tt_as_ntt -+ i -+ (Libcrux.Kem.Kyber.Serialize.deserialize_to_uncompressed_ring_element tt_as_ntt_bytes -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ <: -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ in -+ admit(); //P-F -+ tt_as_ntt -+#pop-options -+ -+#push-options "--split_queries always" -+let deserialize_secret_key (#p:Spec.Kyber.params) (v_K: usize) (secret_key: t_Slice u8) = -+ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat wfZero v_K -+ in -+ let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> True in -+ let sl : t_Slice u8 = secret_key in -+ let chunk_len = Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT in -+ assert(v chunk_len == 384); -+ assert(Seq.length secret_key == v (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)); -+ assert(Seq.length secret_key == (v v_K * 256 * 12)/8); -+ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv -+ sl -+ chunk_len -+ secret_as_ntt -+ (fun secret_as_ntt temp_1_ -> -+ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ secret_as_ntt -+ in -+ let i, secret_bytes:(usize & t_Array u8 chunk_len) = temp_1_ in -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt -+ i -+ (Libcrux.Kem.Kyber.Serialize.deserialize_to_uncompressed_ring_element secret_bytes -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ <: -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ in -+ admit(); //P-F -+ secret_as_ntt -+#pop-options -+ -+#push-options "--z3rlimit 400 --split_queries no" -+let decrypt #p - (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: - usize) -- (secret_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) -- = -- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- deserialize_then_decompress_u v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR ciphertext -+ (secret_key: t_Slice u8) -+ (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = -+ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ deserialize_then_decompress_u #p v_K -+ v_CIPHERTEXT_SIZE -+ v_VECTOR_U_ENCODED_SIZE -+ v_U_COMPRESSION_FACTOR -+ ciphertext - in -- let v:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_ring_element_v v_V_COMPRESSION_FACTOR -+ let v:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_ring_element_v #p v_V_COMPRESSION_FACTOR - (ciphertext.[ { Core.Ops.Range.f_start = v_VECTOR_U_ENCODED_SIZE } - <: - Core.Ops.Range.t_RangeFrom usize ] - <: - t_Slice u8) - in -- let message:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Matrix.compute_message v_K v secret_as_ntt u_as_ntt -+ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ deserialize_secret_key #p v_K secret_key - in -- Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message -+ let message:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Matrix.compute_message #p v_K v secret_as_ntt u_as_ntt -+ in -+ let res = Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message in -+ res -+#pop-options - --let encrypt -- (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: -- usize) -- (public_key: t_Slice u8) -+#push-options "--z3rlimit 200" -+let encrypt #p -+ v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE -+ public_key - (message: t_Array u8 (sz 32)) -- (randomness: t_Slice u8) -- = -- let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Libcrux.Kem.Kyber.Serialize.deserialize_ring_elements_reduced v_T_AS_NTT_ENCODED_SIZE -- v_K -+ (randomness: t_Slice u8) = -+ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ deserialize_public_key #p v_K - (public_key.[ { Core.Ops.Range.f_end = v_T_AS_NTT_ENCODED_SIZE } - <: - Core.Ops.Range.t_RangeTo usize ] -@@ -361,82 +387,98 @@ - <: - Core.Ops.Range.t_RangeFrom usize ] - in -- let a_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -- Libcrux.Kem.Kyber.Matrix.sample_matrix_A v_K -+ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = -+ Libcrux.Kem.Kyber.Matrix.sample_matrix_A #p v_K - (into_padded_array (sz 34) seed <: t_Array u8 (sz 34)) - false - in -- encrypt_unpacked v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN -- v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 -- v_ETA2_RANDOMNESS_SIZE tt_as_ntt a_transpose message randomness -- --let deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) = -- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -+ let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = into_padded_array (sz 33) randomness in -+ let r_as_ntt, domain_separator:(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & -+ u8) = -+ sample_vector_cbd_then_ntt #p v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy - in -- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact secret_key -- Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT -- <: -- Core.Slice.Iter.t_ChunksExact u8) -+ assert (v domain_separator == v v_K); -+ let tmp0, tmp1, out:(t_Array u8 (sz 33) & u8 & -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = -+ sample_vector_cbd #p v_K v_ETA2_RANDOMNESS_SIZE v_ETA2 prf_input domain_separator -+ in -+ let prf_input:t_Array u8 (sz 33) = tmp0 in -+ let domain_separator:u8 = tmp1 in -+ let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = out in -+ let prf_input:t_Array u8 (sz 33) = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_input (sz 32) domain_separator -+ in -+ assert (Seq.equal prf_input (Seq.append randomness (Seq.create 1 domain_separator))); -+ assert (prf_input == Seq.append randomness (Seq.create 1 domain_separator)); -+ let (prf_output: t_Array u8 v_ETA2_RANDOMNESS_SIZE):t_Array u8 v_ETA2_RANDOMNESS_SIZE = -+ Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE -+ (Rust_primitives.unsize prf_input <: t_Slice u8) -+ in -+ let error_2_:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1) = -+ Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA2 -+ (Rust_primitives.unsize prf_output <: t_Slice u8) -+ in -+ let error_2_:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b error_2_ in -+ let u:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Libcrux.Kem.Kyber.Matrix.compute_vector_u #p v_K v_A_transpose r_as_ntt error_1_ -+ in -+ let message_as_ring_element:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_message message -+ in -+ let v:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Matrix.compute_ring_element_v #p v_K -+ tt_as_ntt -+ r_as_ntt -+ error_2_ -+ message_as_ring_element -+ in -+ let c1:t_Array u8 v_C1_LEN = -+ compress_then_serialize_u #p v_K v_C1_LEN v_U_COMPRESSION_FACTOR v_BLOCK_LEN u -+ in -+ let c2:t_Array u8 v_C2_LEN = -+ Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_v #p v_V_COMPRESSION_FACTOR -+ v_C2_LEN -+ v -+ in -+ assert (v_C1_LEN = Spec.Kyber.v_C1_SIZE p); -+ assert (v_C2_LEN = Spec.Kyber.v_C2_SIZE p); -+ assert (v_CIPHERTEXT_SIZE == v_C1_LEN +! v_C2_LEN); -+ assert (v_C1_LEN <=. v_CIPHERTEXT_SIZE); -+ let (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE):t_Array u8 v_CIPHERTEXT_SIZE = -+ into_padded_array v_CIPHERTEXT_SIZE (Rust_primitives.unsize c1 <: t_Slice u8) -+ in -+ let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from ciphertext -+ ({ Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize) -+ (Core.Slice.impl__copy_from_slice (ciphertext.[ { Core.Ops.Range.f_start = v_C1_LEN } -+ <: -+ Core.Ops.Range.t_RangeFrom usize ] - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ t_Slice u8) -+ (Core.Array.impl_23__as_slice v_C2_LEN c2 <: t_Slice u8) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- secret_as_ntt -- (fun secret_as_ntt temp_1_ -> -- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- secret_as_ntt -- in -- let i, secret_bytes:(usize & t_Slice u8) = temp_1_ in -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt -- i -- (Libcrux.Kem.Kyber.Serialize.deserialize_to_uncompressed_ring_element secret_bytes -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ t_Slice u8) + let ind_cpa_private_key, public_key:(t_Array u8 v_CPA_PRIVATE_KEY_SIZE & + t_Array u8 v_PUBLIC_KEY_SIZE) = +- Libcrux.Kem.Kyber.Ind_cpa.generate_keypair v_K ++ Libcrux.Kem.Kyber.Ind_cpa.generate_keypair #p v_K + v_CPA_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT +@@ -414,7 +362,7 @@ + ind_cpa_keypair_randomness in -- secret_as_ntt -+ lemma_slice_append ciphertext c1 c2; -+ ciphertext -+#pop-options + let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = +- serialize_kem_secret_key v_PRIVATE_KEY_SIZE ++ serialize_kem_secret_key #p v_PRIVATE_KEY_SIZE + (Rust_primitives.unsize ind_cpa_private_key <: t_Slice u8) + (Rust_primitives.unsize public_key <: t_Slice u8) + implicit_rejection_value +@@ -428,59 +376,3 @@ + private_key + (Core.Convert.f_into public_key <: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) --let decrypt -- (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: +-let generate_keypair_unpacked +- (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) -- (secret_key: t_Slice u8) -- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- (randomness: t_Array u8 (sz 64)) - = -- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- deserialize_secret_key v_K secret_key -- in -- decrypt_unpacked v_K -- v_CIPHERTEXT_SIZE -- v_VECTOR_U_ENCODED_SIZE -- v_U_COMPRESSION_FACTOR -- v_V_COMPRESSION_FACTOR -- secret_as_ntt -- ciphertext -- --let serialize_secret_key -+let serialize_secret_key (#p:Spec.Kyber.params) - (v_K v_OUT_LEN: usize) -- (key: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- = -+ (key: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = - let out:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in -+ let orig_out = out in -+ let acc_t = t_Array u8 v_OUT_LEN in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> True in - let out:t_Array u8 v_OUT_LEN = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Iter.Traits.Collect.f_into_iter key -- <: -- Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- let ind_cpa_keypair_randomness:t_Slice u8 = +- randomness.[ { +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +- } +- <: +- Core.Ops.Range.t_Range usize ] +- in +- let implicit_rejection_value:t_Slice u8 = +- randomness.[ { +- Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +- } +- <: +- Core.Ops.Range.t_RangeFrom usize ] +- in +- let (secret_as_ntt, tt_as_ntt, a_transpose), ind_cpa_public_key:((t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & +- t_Array u8 v_PUBLIC_KEY_SIZE) = +- Libcrux.Kem.Kyber.Ind_cpa.generate_keypair_unpacked v_K +- v_PUBLIC_KEY_SIZE +- v_BYTES_PER_RING_ELEMENT +- v_ETA1 +- v_ETA1_RANDOMNESS_SIZE +- ind_cpa_keypair_randomness +- in +- let ind_cpa_public_key_hash:t_Array u8 (sz 32) = +- Libcrux.Kem.Kyber.Hash_functions.v_H (Rust_primitives.unsize ind_cpa_public_key <: t_Slice u8) +- in +- let (rej: t_Array u8 (sz 32)):t_Array u8 (sz 32) = +- Core.Result.impl__unwrap (Core.Convert.f_try_into implicit_rejection_value - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -+ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #acc_t #inv -+ key - out - (fun out temp_1_ -> - let out:t_Array u8 v_OUT_LEN = out in -- let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = temp_1_ in -+ let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = temp_1_ in - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out - ({ - Core.Ops.Range.f_start -@@ -475,13 +517,14 @@ - <: - t_Array u8 v_OUT_LEN) - in -+ admit(); //P-F - out +- Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError) +- in +- let (pubkey: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE):Libcrux.Kem.Kyber.Types.t_MlKemPublicKey +- v_PUBLIC_KEY_SIZE = +- Core.Convert.f_from ind_cpa_public_key +- in +- ({ +- f_secret_as_ntt = secret_as_ntt; +- f_t_as_ntt = tt_as_ntt; +- f_a_transpose = a_transpose; +- f_rej = rej; +- f_ind_cpa_public_key_hash = ind_cpa_public_key_hash +- } +- <: +- t_MlKemState v_K), +- pubkey +- <: +- (t_MlKemState v_K & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +diff -ruN extraction/Libcrux.Kem.Kyber.fsti extraction-edited/Libcrux.Kem.Kyber.fsti +--- extraction/Libcrux.Kem.Kyber.fsti 2024-05-14 15:56:45.375357319 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.fsti 2024-05-14 15:56:45.443356204 +0200 +@@ -6,65 +6,88 @@ + unfold + let t_MlKemSharedSecret = t_Array u8 (sz 32) --let serialize_public_key +-/// Seed size for key generation + let v_KEY_GENERATION_SEED_SIZE: usize = + Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +! + Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + +-/// Serialize the secret key. +-val serialize_kem_secret_key ++val serialize_kem_secret_key (#p:Spec.Kyber.params) + (v_SERIALIZED_KEY_LEN: usize) + (private_key public_key implicit_rejection_value: t_Slice u8) +- : Prims.Pure (t_Array u8 v_SERIALIZED_KEY_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ : Pure (t_Array u8 v_SERIALIZED_KEY_LEN) ++ (requires (length private_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ ++ length public_key == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ length implicit_rejection_value == Spec.Kyber.v_SHARED_SECRET_SIZE /\ ++ v_SERIALIZED_KEY_LEN == Spec.Kyber.v_SECRET_KEY_SIZE p)) ++ (ensures (fun res -> res == ++ Seq.append private_key ( ++ Seq.append public_key ( ++ Seq.append (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value)))) + +-val decapsulate ++val decapsulate (#p:Spec.Kyber.params) + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) ++ : Pure (t_Array u8 (sz 32)) ++ (requires ( p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ ++ Spec.Kyber.valid_params p /\ ++ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ ++ v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ ++ v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p /\ ++ v_SECRET_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ ++ v_CPA_SECRET_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ ++ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ ++ v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ ++ v_C1_BLOCK_SIZE == Spec.Kyber.v_C1_BLOCK_SIZE p /\ ++ v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ ++ v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p ++ )) ++ (ensures (fun res -> ++ res == Spec.Kyber.ind_cca_decapsulate p secret_key.f_value ciphertext.f_value)) + +-val encapsulate ++val encapsulate (#p:Spec.Kyber.params) + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) +- : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) ++ (requires (p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ ++ Spec.Kyber.valid_params p /\ ++ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ ++ v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ ++ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ ++ v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ ++ v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ ++ v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p /\ ++ v_VECTOR_U_BLOCK_LEN == Spec.Kyber.v_C1_BLOCK_SIZE p ++ )) + +-val validate_public_key ++ (ensures (fun (ct,ss) -> ++ (ct.f_value,ss) == Spec.Kyber.ind_cca_encapsulate p public_key.f_value randomness)) + -+let serialize_public_key (#p:Spec.Kyber.params) ++val validate_public_key (#p:Spec.Kyber.params) (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) -- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- (seed_for_a: t_Slice u8) -- = -+ (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (seed_for_a: t_Slice u8) = - let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = - Rust_primitives.Hax.repeat 0uy v_PUBLIC_KEY_SIZE - in -@@ -498,7 +541,7 @@ - Core.Ops.Range.t_Range usize ] - <: - t_Slice u8) -- (Rust_primitives.unsize (serialize_secret_key v_K -+ (Rust_primitives.unsize (serialize_secret_key #p v_K - v_RANKED_BYTES_PER_RING_ELEMENT - tt_as_ntt - <: -@@ -524,232 +567,49 @@ - <: - t_Slice u8) - in -+ lemma_slice_append public_key_serialized -+ (Spec.Kyber.vector_encode_12 (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p tt_as_ntt)) -+ seed_for_a; - public_key_serialized + (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) +- : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) +- +-type t_MlKemState (v_K: usize) = { +- f_secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K; +- f_t_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K; +- f_a_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K; +- f_rej:t_Array u8 (sz 32); +- f_ind_cpa_public_key_hash:t_Array u8 (sz 32) +-} +- +-val decapsulate_unpacked +- (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: +- usize) +- (state: t_MlKemState v_K) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +- +-val generate_keypair +- (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: +- usize) +- (randomness: t_Array u8 (sz 64)) +- : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Prims.Pure bool ++ (requires (v_K == p.v_RANK /\ ++ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p ++ )) ++ (ensures (fun _ -> Prims.l_True)) --let generate_keypair_unpacked -- (v_K v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) -- (key_generation_seed: t_Slice u8) -- = -+ -+let generate_keypair #p -+ (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: -+ usize) -+ (key_generation_seed: t_Slice u8) = - let hashed:t_Array u8 (sz 64) = Libcrux.Kem.Kyber.Hash_functions.v_G key_generation_seed in - let seed_for_A, seed_for_secret_and_error:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) (sz 32) - in -- let a_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -- Libcrux.Kem.Kyber.Matrix.sample_matrix_A v_K -+ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = -+ Libcrux.Kem.Kyber.Matrix.sample_matrix_A #p v_K - (into_padded_array (sz 34) seed_for_A <: t_Array u8 (sz 34)) - true - in - let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = - into_padded_array (sz 33) seed_for_secret_and_error - in -- let secret_as_ntt, domain_separator:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ let secret_as_ntt, domain_separator:(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - v_K & - u8) = -- sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy -+ sample_vector_cbd_then_ntt #p v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy - in -- let error_as_ntt, _:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & u8) = -- sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input domain_separator -+ let error_as_ntt, _:(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & u8) = -+ sample_vector_cbd_then_ntt #p v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input domain_separator - in -- let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Libcrux.Kem.Kyber.Matrix.compute_As_plus_e v_K a_transpose secret_as_ntt error_as_ntt -+ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Libcrux.Kem.Kyber.Matrix.compute_As_plus_e #p v_K v_A_transpose secret_as_ntt error_as_ntt - in - let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = -- serialize_public_key v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE tt_as_ntt seed_for_A -+ serialize_public_key #p v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE tt_as_ntt seed_for_A - in -- let secret_as_ntt, tt_as_ntt:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = +-val generate_keypair_unpacked ++val generate_keypair (#p:Spec.Kyber.params) + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) +- : Prims.Pure (t_MlKemState v_K & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) ++ (requires (v_K == p.v_RANK /\ v_ETA1 == p.v_ETA1 /\ ++ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ ++ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ v_CPA_PRIVATE_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ ++ v_PRIVATE_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ ++ v_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p ++ )) ++ (ensures (fun kp -> ++ (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.ind_cca_generate_keypair p randomness)) +diff -ruN extraction/Libcrux.Kem.Kyber.Hash_functions.fst extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst +--- extraction/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-14 15:56:45.405356827 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-14 15:56:45.450356089 +0200 +@@ -3,129 +3,114 @@ + open Core + open FStar.Mul + +-let v_G (input: t_Slice u8) = Libcrux.Digest.sha3_512_ input +- +-let v_H (input: t_Slice u8) = Libcrux.Digest.sha3_256_ input +- +-let v_PRF (v_LEN: usize) (input: t_Slice u8) = Libcrux.Digest.shake256 v_LEN input +- +-let absorb (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) = +- let _:Prims.unit = +- if true ++let v_G (input: t_Slice u8) = ++ let res = Libcrux.Digest.sha3_512_ input in ++ admit(); // We assume that sha3_512 correctly implements G ++ res ++ ++let v_H (input: t_Slice u8) = ++ let res = Libcrux.Digest.sha3_256_ input in ++ admit(); // We assume that sha3_512 correctly implements H ++ res ++ ++let v_PRF (v_LEN: usize) (input: t_Slice u8) = ++ let res = Libcrux.Digest.shake256 v_LEN input in ++ admit(); // We assume that sha3_512 correctly implements H ++ res ++ ++let v_XOFx4 v_K (input: t_Array (t_Array u8 (sz 34)) v_K) = ++ assert (v v_K >= 2); ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 840) <: t_Array u8 (sz 840)) v_K ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ if ~.(Libcrux_platform.Platform.simd256_support () <: bool) + then +- let _:Prims.unit = +- if ~.((v_K =. sz 2 <: bool) || (v_K =. sz 3 <: bool) || (v_K =. sz 4 <: bool)) +- then +- Rust_primitives.Hax.never_to_any (Core.Panicking.panic "assertion failed: K == 2 || K == 3 || K == 4" +- ++ Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ Core.Ops.Range.f_start = sz 0; ++ Core.Ops.Range.f_end = v_K ++ } + <: +- Rust_primitives.Hax.t_Never) +- in +- () +- in +- let state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = +- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__new () +- in +- let (data: t_Array (t_Slice u8) v_K):t_Array (t_Slice u8) v_K = +- Rust_primitives.Hax.repeat (Rust_primitives.unsize (let list = [0uy] in +- FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 1); +- Rust_primitives.Hax.array_of_list 1 list) +- <: +- t_Slice u8) +- v_K +- in +- let data:t_Array (t_Slice u8) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K @@ -2715,110 +2296,37 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-edited/Libcrux.Kem - Core.Ops.Range.t_Range usize) - <: - Core.Ops.Range.t_Range usize) -- (secret_as_ntt, tt_as_ntt -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -- (fun temp_0_ i -> -- let secret_as_ntt, tt_as_ntt:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -- temp_0_ -- in +- data +- (fun data i -> +- let data:t_Array (t_Slice u8) v_K = data in - let i:usize = i in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end -- = -- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- (secret_as_ntt, tt_as_ntt -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -- (fun temp_0_ j -> -- let secret_as_ntt, tt_as_ntt:(t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -- temp_0_ -- in -- let j:usize = j in -- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt -- i -- ({ -- (secret_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- ) with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (secret_as_ntt.[ -- i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- j -- (cast (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative ((secret_as_ntt.[ -- i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] -- <: -- i32) -- <: -- u16) -- <: -- i32) -- <: -- t_Array i32 (sz 256) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- in -- let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize tt_as_ntt -- i -- ({ -- (tt_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (tt_as_ntt.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- j -- (cast (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative ((tt_as_ntt.[ -- i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] -- <: -- i32) -- <: -- u16) -- <: -- i32) -- <: -- t_Array i32 (sz 256) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- in -- secret_as_ntt, tt_as_ntt -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize data +- i +- (Rust_primitives.unsize (input.[ i ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ Core.Ops.Range.t_Range usize) + <: +- t_Array (t_Slice u8) v_K) - in -- let a_matrix:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -- a_transpose +- let state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = +- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__absorb_final v_K state data - in -- let a_matrix:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- state +- +-let free_state (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = +- let _:Prims.unit = Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__free_memory xof_state in +- () +- +-let squeeze_block (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = +- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & +- t_Array (t_Array u8 (sz 168)) v_K) = +- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__squeeze_blocks (sz 168) v_K xof_state +- in +- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in +- let (output: t_Array (t_Array u8 (sz 168)) v_K):t_Array (t_Array u8 (sz 168)) v_K = out1 in +- let out:t_Array (t_Array u8 (sz 168)) v_K = +- Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 168) <: t_Array u8 (sz 168)) v_K +- in +- let out:t_Array (t_Array u8 (sz 168)) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K @@ -2827,6292 +2335,6814 @@ diff -ruN extraction/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-edited/Libcrux.Kem - Core.Ops.Range.t_Range usize) - <: - Core.Ops.Range.t_Range usize) -- a_matrix -- (fun a_matrix i -> -- let a_matrix:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- v_K = -- a_matrix -- in +- out +- (fun out i -> +- let out:t_Array (t_Array u8 (sz 168)) v_K = out in - let i:usize = i in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = v_K -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- a_matrix -- (fun a_matrix j -> -- let a_matrix:t_Array -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -- a_matrix -- in -- let j:usize = j in -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize a_matrix -- i -- (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (a_matrix.[ i ] -- <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- j -- ((a_transpose.[ j ] -- <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K).[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- <: -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out +- i +- (output.[ i ] <: t_Array u8 (sz 168)) - <: -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- t_Array (t_Array u8 (sz 168)) v_K) - in -- (secret_as_ntt, tt_as_ntt, a_matrix -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K)), -- public_key_serialized +- let hax_temp_output:t_Array (t_Array u8 (sz 168)) v_K = out in +- xof_state, hax_temp_output - <: -- ((t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & -- t_Array u8 v_PUBLIC_KEY_SIZE) +- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 168)) v_K) - --let generate_keypair -- (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: -- usize) -- (key_generation_seed: t_Slice u8) -- = -- let (secret_as_ntt, v__t_as_ntt, v__a_transpose), public_key_serialized:((t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & -- t_Array u8 v_PUBLIC_KEY_SIZE) = -- generate_keypair_unpacked v_K -- v_PUBLIC_KEY_SIZE -- v_RANKED_BYTES_PER_RING_ELEMENT -- v_ETA1 -- v_ETA1_RANDOMNESS_SIZE -- key_generation_seed +-let squeeze_three_blocks (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = +- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & +- t_Array (t_Array u8 (sz 504)) v_K) = +- Libcrux.Digest.Incremental_x4.impl__Shake128StateX4__squeeze_blocks (sz 504) v_K xof_state - in - let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = -- serialize_secret_key v_K v_PRIVATE_KEY_SIZE secret_as_ntt -+ serialize_secret_key #p v_K v_PRIVATE_KEY_SIZE secret_as_ntt +- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in +- let (output: t_Array (t_Array u8 (sz 504)) v_K):t_Array (t_Array u8 (sz 504)) v_K = out1 in +- let out:t_Array (t_Array u8 (sz 504)) v_K = +- Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 504) <: t_Array u8 (sz 504)) v_K +- in +- let out:t_Array (t_Array u8 (sz 504)) v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = v_K +- } ++ Core.Ops.Range.t_Range usize) ++ out ++ (fun out i -> ++ let out:t_Array (t_Array u8 (sz 840)) v_K = out in ++ let i:usize = i in ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out ++ i ++ (Libcrux.Digest.shake128 (sz 840) ++ (Rust_primitives.unsize (input.[ i ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ <: ++ t_Array u8 (sz 840)) + <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) ++ t_Array (t_Array u8 (sz 840)) v_K) ++ else ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ match cast (v_K <: usize) <: u8 with ++ | 2uy -> ++ let d0, d1, _, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & ++ t_Array u8 (sz 840)) = ++ Libcrux.Digest.shake128x4 (sz 840) ++ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) d0 ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) d1 ++ in ++ out ++ | 3uy -> ++ assert (v (cast v_K <: u8) = 3); ++ let d0, d1, d2, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & ++ t_Array u8 (sz 840)) = ++ Libcrux.Digest.shake128x4 (sz 840) ++ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) d0 ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) d1 ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) d2 ++ in ++ out ++ | 4uy -> ++ assert (v (cast v_K <: u8) = 4); ++ let d0, d1, d2, d3:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & ++ t_Array u8 (sz 840)) = ++ Libcrux.Digest.shake128x4 (sz 840) ++ (Rust_primitives.unsize (input.[ sz 0 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 1 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 2 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ (Rust_primitives.unsize (input.[ sz 3 ] <: t_Array u8 (sz 34)) <: t_Slice u8) ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 0) d0 ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 1) d1 ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 2) d2 ++ in ++ let out:t_Array (t_Array u8 (sz 840)) v_K = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out (sz 3) d3 ++ in ++ out ++ | _ -> out ++ in + out +- (fun out i -> +- let out:t_Array (t_Array u8 (sz 504)) v_K = out in +- let i:usize = i in +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out +- i +- (output.[ i ] <: t_Array u8 (sz 504)) +- <: +- t_Array (t_Array u8 (sz 504)) v_K) in -+ let res = - secret_key_serialized, public_key_serialized - <: - (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) -+ in -+ res -+ -diff -ruN extraction/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti ---- extraction/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-07 18:38:45 -@@ -1,196 +1,151 @@ - module Libcrux.Kem.Kyber.Ind_cpa --#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +- let hax_temp_output:t_Array (t_Array u8 (sz 504)) v_K = out in +- xof_state, hax_temp_output +- <: +- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 504)) v_K) ++ admit(); // We assume that shake128x4 correctly implements XOFx4 ++ out +diff -ruN extraction/Libcrux.Kem.Kyber.Hash_functions.fsti extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti +--- extraction/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-14 15:56:45.382357204 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-14 15:56:45.453356039 +0200 +@@ -3,35 +3,17 @@ open Core open FStar.Mul --/// Pad the `slice` with `0`s at the end. --val into_padded_array (v_LEN: usize) (slice: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) -+val into_padded_array (v_LEN: usize) (slice: t_Slice u8) : -+ Pure (t_Array u8 v_LEN) -+ (requires (length slice <=. v_LEN)) -+ (ensures (fun res -> Seq.slice res 0 (Seq.length slice) == slice)) +-let v_BLOCK_SIZE: usize = sz 168 ++val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True ++ (ensures (fun res -> res == Spec.Kyber.v_G input)) --/// Sample a vector of ring elements from a centered binomial distribution. --val sample_ring_element_cbd -+val sample_vector_cbd (#p:Spec.Kyber.params) - (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) - (prf_input: t_Array u8 (sz 33)) - (domain_separator: u8) +-val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) +- +-val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) ++val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True ++ (ensures (fun res -> res == Spec.Kyber.v_H input)) + + val v_PRF (v_LEN: usize) (input: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) +- +-let v_THREE_BLOCKS: usize = v_BLOCK_SIZE *! sz 3 +- +-val absorb (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) +- : Prims.Pure Libcrux.Digest.Incremental_x4.t_Shake128StateX4 +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// Free the memory of the state. +-/// **NOTE:** That this needs to be done manually for now. +-val free_state (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) +- : Prims.Pure Prims.unit Prims.l_True (fun _ -> Prims.l_True) +- +-val squeeze_block (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) - : Prims.Pure -- (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 168)) v_K) - Prims.l_True - (fun _ -> Prims.l_True) -+ : Pure (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (requires v domain_separator <= v v_K /\ v_K <=. sz 4 /\ -+ v_K = p.v_RANK /\ v_ETA2 = p.v_ETA2 /\ -+ v_ETA2_RANDOMNESS_SIZE = Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p) -+ (ensures (fun (prf,ds,x) -> v ds == v domain_separator + v v_K /\ -+ Seq.slice prf 0 32 == Seq.slice prf_input 0 32 /\ -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p x == -+ Spec.Kyber.sample_vector_cbd #p (Seq.slice prf_input 0 32) (sz (v domain_separator)))) - --/// Sample a vector of ring elements from a centered binomial distribution and --/// convert them into their NTT representations. --val sample_vector_cbd_then_ntt -+ -+val sample_vector_cbd_then_ntt (#p:Spec.Kyber.params) - (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) - (prf_input: t_Array u8 (sz 33)) -- (domain_separator: u8) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & u8) +- +-val squeeze_three_blocks (v_K: usize) (xof_state: Libcrux.Digest.Incremental_x4.t_Shake128StateX4) +- : Prims.Pure +- (Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & t_Array (t_Array u8 (sz 504)) v_K) - Prims.l_True - (fun _ -> Prims.l_True) -+ (domain_separator: u8{v domain_separator <= v v_K /\ v_K <=. sz 4}) -+ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & u8) -+ (requires (v_K == p.v_RANK /\ v_ETA == p.v_ETA1 /\ v_ETA_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p)) -+ (ensures (fun (x,ds) -> v ds == v domain_separator + v v_K /\ -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p x == -+ Spec.Kyber.sample_vector_cbd_then_ntt #p (Seq.slice prf_input 0 32) (sz (v domain_separator)))) ++ : Prims.Pure (t_Array u8 v_LEN) Prims.l_True ++ (ensures (fun res -> res == Spec.Kyber.v_PRF v_LEN input)) ++ ++val v_XOFx4 (v_K: usize{v v_K >= 2 /\ v v_K <= 4}) (input: t_Array (t_Array u8 (sz 34)) v_K) ++ : Prims.Pure (t_Array (t_Array u8 (sz 840)) v_K) Prims.l_True ++ (ensures (fun res -> ++ (forall i. i < v v_K ==> Seq.index res i == Spec.Kyber.v_XOF (sz 840) (Seq.index input i)))) +diff -ruN extraction/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst +--- extraction/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-14 15:56:45.388357106 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-14 15:56:45.460355925 +0200 +@@ -1,5 +1,5 @@ + module Libcrux.Kem.Kyber.Ind_cpa +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" + open Core + open FStar.Mul --/// Call [`compress_then_serialize_ring_element_u`] on each ring element. --val compress_then_serialize_u -+val compress_then_serialize_u (#p:Spec.Kyber.params) - (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) -- (input: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) -+ (input: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ : Pure (t_Array u8 v_OUT_LEN) -+ (requires (v_K == p.v_RANK /\ v_OUT_LEN == Spec.Kyber.v_C1_SIZE p /\ -+ v_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR /\ -+ v_BLOCK_LEN = Spec.Kyber.v_C1_BLOCK_SIZE p)) -+ (ensures (fun res -> -+ res == Spec.Kyber.compress_then_encode_u p -+ (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p input))) - --/// This function implements Algorithm 13 of the --/// NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. --/// Algorithm 13 is reproduced below: --/// ```plaintext --/// Input: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. --/// Input: message m ∈ 𝔹^{32}. --/// Input: encryption randomness r ∈ 𝔹^{32}. --/// Output: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. --/// N ← 0 --/// t̂ ← ByteDecode₁₂(ekₚₖₑ[0:384k]) --/// ρ ← ekₚₖₑ[384k: 384k + 32] --/// for (i ← 0; i < k; i++) --/// for(j ← 0; j < k; j++) --/// Â[i,j] ← SampleNTT(XOF(ρ, i, j)) --/// end for --/// end for --/// for(i ← 0; i < k; i++) --/// r[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(r,N)) --/// N ← N + 1 --/// end for --/// for(i ← 0; i < k; i++) --/// e₁[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) --/// N ← N + 1 --/// end for --/// e₂ ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) --/// r̂ ← NTT(r) --/// u ← NTT-¹(Âᵀ ◦ r̂) + e₁ --/// μ ← Decompress₁(ByteDecode₁(m))) --/// v ← NTT-¹(t̂ᵀ ◦ rˆ) + e₂ + μ --/// c₁ ← ByteEncode_{dᵤ}(Compress_{dᵤ}(u)) --/// c₂ ← ByteEncode_{dᵥ}(Compress_{dᵥ}(v)) --/// return c ← (c₁ ‖ c₂) --/// ``` --/// The NIST FIPS 203 standard can be found at --/// . --val encrypt_unpacked -- (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: -- usize) -- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- (a_transpose: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- (message: t_Array u8 (sz 32)) -- (randomness: t_Slice u8) -- : Prims.Pure (t_Array u8 v_CIPHERTEXT_SIZE) Prims.l_True (fun _ -> Prims.l_True) -- --/// Call [`deserialize_then_decompress_ring_element_u`] on each ring element --/// in the `ciphertext`. --val deserialize_then_decompress_u -- (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) -+val deserialize_then_decompress_u (#p:Spec.Kyber.params) -+ (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR: usize) - (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (requires v_K == p.v_RANK /\ -+ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -+ v_VECTOR_U_ENCODED_SIZE == Spec.Kyber.v_C1_SIZE p /\ -+ v_U_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR) -+ (ensures fun res -> -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res == -+ Spec.Kyber.(vector_ntt (decode_then_decompress_u p (Seq.slice ciphertext 0 (v (Spec.Kyber.v_C1_SIZE p)))))) +@@ -37,33 +37,37 @@ + in + out --/// This function implements Algorithm 14 of the --/// NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. --/// Algorithm 14 is reproduced below: --/// ```plaintext --/// Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. --/// Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. --/// Output: message m ∈ 𝔹^{32}. --/// c₁ ← c[0 : 32dᵤk] --/// c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] --/// u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) --/// v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) --/// ŝ ← ByteDecode₁₂(dkₚₖₑ) --/// w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) --/// m ← ByteEncode₁(Compress₁(w)) --/// return m --/// ``` --/// The NIST FIPS 203 standard can be found at --/// . --val decrypt_unpacked -+val deserialize_public_key (#p:Spec.Kyber.params) -+ (v_K: usize) (public_key: t_Array u8 (Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p)) -+ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (requires v_K == p.v_RANK /\ -+ length public_key == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p) -+ (ensures fun res -> -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b res == -+ Spec.Kyber.vector_decode_12 #p public_key) -+ -+val deserialize_secret_key (#p:Spec.Kyber.params) (v_K: usize) (secret_key: t_Slice u8) -+ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (requires v_K == p.v_RANK /\ -+ length secret_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p) -+ (ensures fun res -> -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res == -+ Spec.Kyber.vector_decode_12 #p secret_key) -+ +-let sample_ring_element_cbd ++unfold let acc_t (v_K v_ETA:usize) = (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1)) v_K) ++unfold let inv_t v_K v_ETA = acc_t v_K v_ETA -> usize -> Type + -+val decrypt (#p:Spec.Kyber.params) - (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: - usize) -- (secret_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ (secret_key: t_Slice u8) - (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -+ : Pure (t_Array u8 (sz 32)) -+ (requires (v_K == p.v_RANK /\ -+ length secret_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -+ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -+ v_VECTOR_U_ENCODED_SIZE == Spec.Kyber.v_C1_SIZE p /\ -+ v_U_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR /\ -+ v_V_COMPRESSION_FACTOR == p.v_VECTOR_V_COMPRESSION_FACTOR)) -+ (ensures (fun res -> -+ res == Spec.Kyber.ind_cpa_decrypt p secret_key ciphertext)) - --val encrypt ++let wfZero: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) + -+val encrypt (#p:Spec.Kyber.params) - (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) - (public_key: t_Slice u8) - (message: t_Array u8 (sz 32)) -- (randomness: t_Slice u8) -- : Prims.Pure (t_Array u8 v_CIPHERTEXT_SIZE) Prims.l_True (fun _ -> Prims.l_True) -- --/// Call [`deserialize_to_uncompressed_ring_element`] for each ring element. --val deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -- --val decrypt -- (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: -- usize) -- (secret_key: t_Slice u8) -- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -- --/// Call [`serialize_uncompressed_ring_element`] for each ring element. --val serialize_secret_key -+ (randomness: t_Slice u8{length randomness <. sz 33}) -+ : Pure (t_Array u8 v_CIPHERTEXT_SIZE) -+ (requires (v_K == p.v_RANK /\ -+ v_ETA1 = p.v_ETA1 /\ -+ v_ETA1_RANDOMNESS_SIZE = Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -+ v_ETA2 = p.v_ETA2 /\ -+ v_BLOCK_LEN == Spec.Kyber.v_C1_BLOCK_SIZE p /\ -+ v_ETA2_RANDOMNESS_SIZE = Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ -+ v_U_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR /\ -+ v_V_COMPRESSION_FACTOR == p.v_VECTOR_V_COMPRESSION_FACTOR /\ -+ length public_key == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ length randomness == Spec.Kyber.v_SHARED_SECRET_SIZE /\ -+ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -+ v_T_AS_NTT_ENCODED_SIZE == Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p /\ -+ v_C1_LEN == Spec.Kyber.v_C1_SIZE p /\ -+ v_C2_LEN == Spec.Kyber.v_C2_SIZE p)) -+ (ensures (fun ct -> ct == Spec.Kyber.ind_cpa_encrypt p public_key message randomness)) -+ -+val serialize_secret_key (#p:Spec.Kyber.params) - (v_K v_OUT_LEN: usize) -- (key: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) -- --/// Concatenate `t` and `ρ` into the public key. --val serialize_public_key -+ (key: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ : Pure (t_Array u8 v_OUT_LEN) -+ (requires (v_K == p.v_RANK /\ v_OUT_LEN == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) -+ (ensures (fun res -> -+ res == Spec.Kyber.vector_encode_12 #p -+ (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p key))) -+ -+val serialize_public_key (#p:Spec.Kyber.params) - (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) -- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) - (seed_for_a: t_Slice u8) -- : Prims.Pure (t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) -+ : Pure (t_Array u8 v_PUBLIC_KEY_SIZE) -+ (requires (v_K == p.v_RANK /\ -+ v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p /\ -+ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ length seed_for_a == sz 32)) -+ (ensures (fun res -> res == Seq.append (Spec.Kyber.vector_encode_12 -+ (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p tt_as_ntt)) -+ seed_for_a)) - --/// This function implements most of Algorithm 12 of the --/// NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation algorithm. --/// We say "most of" since Algorithm 12 samples the required randomness within --/// the function itself, whereas this implementation expects it to be provided --/// through the `key_generation_seed` parameter. --/// Algorithm 12 is reproduced below: --/// ```plaintext --/// Output: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. --/// Output: decryption key dkₚₖₑ ∈ 𝔹^{384k}. --/// d ←$ B --/// (ρ,σ) ← G(d) --/// N ← 0 --/// for (i ← 0; i < k; i++) --/// for(j ← 0; j < k; j++) --/// Â[i,j] ← SampleNTT(XOF(ρ, i, j)) --/// end for --/// end for --/// for(i ← 0; i < k; i++) --/// s[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(σ,N)) --/// N ← N + 1 --/// end for --/// for(i ← 0; i < k; i++) --/// e[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(σ,N)) --/// N ← N + 1 --/// end for --/// ŝ ← NTT(s) --/// ê ← NTT(e) --/// t̂ ← Â◦ŝ + ê --/// ekₚₖₑ ← ByteEncode₁₂(t̂) ‖ ρ --/// dkₚₖₑ ← ByteEncode₁₂(ŝ) --/// ``` --/// The NIST FIPS 203 standard can be found at --/// . --val generate_keypair_unpacked -- (v_K v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) -- (key_generation_seed: t_Slice u8) -- : Prims.Pure -- ((t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & -- t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) -- --val generate_keypair -+val generate_keypair (#p:Spec.Kyber.params) - (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) - (key_generation_seed: t_Slice u8) -- : Prims.Pure (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) -+ (requires (v_K == p.v_RANK /\ -+ v_ETA1 == p.v_ETA1 /\ -+ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -+ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ v_PRIVATE_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -+ v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p /\ -+ length key_generation_seed == Spec.Kyber.v_CPA_PKE_KEY_GENERATION_SEED_SIZE)) -+ (ensures (fun (sk,pk) -> (sk,pk) == Spec.Kyber.ind_cpa_generate_keypair p key_generation_seed)) -+ -+ -diff -ruN extraction/Libcrux.Kem.Kyber.Kyber1024.fst extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst ---- extraction/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-07 18:38:45 -@@ -7,19 +7,19 @@ - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 3168)) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) - = -- Libcrux.Kem.Kyber.decapsulate (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) (sz 1408) -+ Libcrux.Kem.Kyber.decapsulate #Spec.Kyber.kyber1024_params (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) (sz 1408) - (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1600) secret_key ciphertext - - let encapsulate - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) - (randomness: t_Array u8 (sz 32)) - = -- Libcrux.Kem.Kyber.encapsulate (sz 4) (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) -+ Libcrux.Kem.Kyber.encapsulate #Spec.Kyber.kyber1024_params (sz 4) (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) - (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness - - let validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) = - if -- Libcrux.Kem.Kyber.validate_public_key (sz 4) -+ Libcrux.Kem.Kyber.validate_public_key #Spec.Kyber.kyber1024_params (sz 4) - (sz 1536) - (sz 1568) - public_key.Libcrux.Kem.Kyber.Types.f_value -@@ -32,26 +32,8 @@ - <: - Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) - --let decapsulate_unpacked -- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 4)) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) ++let etaZero (v_ETA:usize{v v_ETA >= 1 /\ v v_ETA < pow2 31}): Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA) = ++ (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #(v v_ETA) Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) ++ ++let sample_vector_cbd (#p:Spec.Kyber.params) + (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) +- (prf_input: t_Array u8 (sz 33)) +- (domain_separator: u8) - = -- Libcrux.Kem.Kyber.decapsulate_unpacked (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) -- (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1600) state -- ciphertext -- - let generate_key_pair (randomness: t_Array u8 (sz 64)) = -- Libcrux.Kem.Kyber.generate_keypair (sz 4) -- (sz 1536) -- (sz 3168) -- (sz 1568) -- (sz 1536) -- (sz 2) -- (sz 128) -- randomness -- --let generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) = -- Libcrux.Kem.Kyber.generate_keypair_unpacked (sz 4) -+ Libcrux.Kem.Kyber.generate_keypair #Spec.Kyber.kyber1024_params (sz 4) - (sz 1536) - (sz 3168) - (sz 1568) -diff -ruN extraction/Libcrux.Kem.Kyber.Kyber1024.fsti extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti ---- extraction/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-07 18:38:45 -@@ -71,13 +71,11 @@ - unfold - let t_MlKem1024PublicKey = Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568) - --/// Decapsulate ML-KEM 1024 - val decapsulate - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 3168)) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) - --/// Encapsulate ML-KEM 1024 - val encapsulate - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) - (randomness: t_Array u8 (sz 32)) -@@ -85,29 +83,12 @@ - Prims.l_True - (fun _ -> Prims.l_True) - --/// Validate a public key. --/// Returns `Some(public_key)` if valid, and `None` otherwise. - val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) - : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568))) - Prims.l_True - (fun _ -> Prims.l_True) - --unfold --let t_MlKem1024State = Libcrux.Kem.Kyber.t_MlKemState (sz 4) -- --val decapsulate_unpacked -- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 4)) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -- --/// Generate ML-KEM 1024 Key Pair - val generate_key_pair (randomness: t_Array u8 (sz 64)) - : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair (sz 3168) (sz 1568)) -- Prims.l_True -- (fun _ -> Prims.l_True) -- --val generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) -- : Prims.Pure -- (Libcrux.Kem.Kyber.t_MlKemState (sz 4) & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) - Prims.l_True - (fun _ -> Prims.l_True) -diff -ruN extraction/Libcrux.Kem.Kyber.Kyber512.fst extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst ---- extraction/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-07 18:38:45 -@@ -7,19 +7,19 @@ - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 1632)) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) - = -- Libcrux.Kem.Kyber.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) (sz 640) -+ Libcrux.Kem.Kyber.decapsulate #Spec.Kyber.kyber512_params (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) (sz 640) - (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) secret_key ciphertext - - let encapsulate - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) - (randomness: t_Array u8 (sz 32)) - = -- Libcrux.Kem.Kyber.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) -+ Libcrux.Kem.Kyber.encapsulate #Spec.Kyber.kyber512_params (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) - (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness - - let validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) = - if -- Libcrux.Kem.Kyber.validate_public_key (sz 2) -+ Libcrux.Kem.Kyber.validate_public_key #Spec.Kyber.kyber512_params (sz 2) - (sz 768) - (sz 800) - public_key.Libcrux.Kem.Kyber.Types.f_value -@@ -32,26 +32,8 @@ - <: - Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) +- let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let domain_separator, error_1_, prf_input:(u8 & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array u8 (sz 33)) = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ (prf_input: t_Array u8 (sz 33)) domain_separator = ++ let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = ++ Rust_primitives.Hax.repeat (etaZero (sz (pow2 (v v_ETA2) - 1))) v_K ++ in ++ let orig_domain_separator = domain_separator in ++ [@ inline_let] ++ let inv : inv_t v_K v_ETA2 = fun (acc:acc_t v_K v_ETA2) (i:usize) -> ++ let (domain_separator,prf_input,error_1_) = acc in ++ if (i >=. sz 0 && i <=. v_K) ++ then ++ domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) ++ else true in ++ let (domain_separator, prf_input, error_1_):acc_t v_K (v_ETA2) = ++ Rust_primitives.Iterators.foldi_range #_ #(acc_t v_K (v_ETA2)) #inv { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = v_K + } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- (domain_separator, error_1_, prf_input +- <: +- (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array u8 (sz 33)) +- ) ++ (domain_separator, prf_input, error_1_) + (fun temp_0_ i -> +- let domain_separator, error_1_, prf_input:(u8 & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array u8 (sz 33)) = ++ let domain_separator, prf_input, error_1_:acc_t v_K (v_ETA2) = + temp_0_ + in + let i:usize = i in +@@ -77,49 +81,46 @@ + Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE + (Rust_primitives.unsize prf_input <: t_Slice u8) + in +- let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize error_1_ + i +- (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA2 ++ (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA2 + (Rust_primitives.unsize prf_output <: t_Slice u8) + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) + in +- domain_separator, error_1_, prf_input +- <: +- (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array u8 (sz 33))) ++ domain_separator, prf_input, error_1_) + in +- let hax_temp_output:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = error_1_ in ++ let hax_temp_output:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = error_1_ in ++ admit(); //P-F + prf_input, domain_separator, hax_temp_output + <: +- (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ (t_Array u8 (sz 33) & u8 & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA2)) v_K) --let decapsulate_unpacked -- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 2)) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) +-let sample_vector_cbd_then_ntt ++#push-options "--split_queries no --z3rlimit 300" ++let sample_vector_cbd_then_ntt (#p:Spec.Kyber.params) + (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) +- (prf_input: t_Array u8 (sz 33)) +- (domain_separator: u8) - = -- Libcrux.Kem.Kyber.decapsulate_unpacked (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) -- (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) state -- ciphertext -- - let generate_key_pair (randomness: t_Array u8 (sz 64)) = -- Libcrux.Kem.Kyber.generate_keypair (sz 2) -- (sz 768) -- (sz 1632) -- (sz 800) -- (sz 768) -- (sz 3) -- (sz 192) -- randomness -- --let generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) = -- Libcrux.Kem.Kyber.generate_keypair_unpacked (sz 2) -+ Libcrux.Kem.Kyber.generate_keypair #Spec.Kyber.kyber512_params (sz 2) - (sz 768) - (sz 1632) - (sz 800) -diff -ruN extraction/Libcrux.Kem.Kyber.Kyber512.fsti extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti ---- extraction/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-07 18:38:45 -@@ -71,13 +71,11 @@ - unfold - let t_MlKem512PublicKey = Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800) - --/// Decapsulate ML-KEM 512 - val decapsulate - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 1632)) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) - : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) - --/// Encapsulate ML-KEM 512 - val encapsulate - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) - (randomness: t_Array u8 (sz 32)) -@@ -85,29 +83,12 @@ - Prims.l_True - (fun _ -> Prims.l_True) - --/// Validate a public key. --/// Returns `Some(public_key)` if valid, and `None` otherwise. - val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) - : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800))) - Prims.l_True - (fun _ -> Prims.l_True) - --unfold --let t_MlKem512State = Libcrux.Kem.Kyber.t_MlKemState (sz 2) -- --val decapsulate_unpacked -- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 2)) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -- --/// Generate ML-KEM 512 Key Pair - val generate_key_pair (randomness: t_Array u8 (sz 64)) - : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair (sz 1632) (sz 800)) -- Prims.l_True -- (fun _ -> Prims.l_True) -- --val generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) -- : Prims.Pure -- (Libcrux.Kem.Kyber.t_MlKemState (sz 2) & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) - Prims.l_True - (fun _ -> Prims.l_True) -diff -ruN extraction/Libcrux.Kem.Kyber.Kyber768.fst extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst ---- extraction/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-07 18:38:45 -@@ -7,19 +7,19 @@ - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 2400)) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) - = -- Libcrux.Kem.Kyber.decapsulate (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) (sz 960) -+ Libcrux.Kem.Kyber.decapsulate #Spec.Kyber.kyber768_params (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) (sz 960) - (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1120) secret_key ciphertext - - let encapsulate - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) - (randomness: t_Array u8 (sz 32)) - = -- Libcrux.Kem.Kyber.encapsulate (sz 3) (sz 1088) (sz 1184) (sz 1152) (sz 960) (sz 128) (sz 10) -+ Libcrux.Kem.Kyber.encapsulate #Spec.Kyber.kyber768_params (sz 3) (sz 1088) (sz 1184) (sz 1152) (sz 960) (sz 128) (sz 10) - (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness - - let validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) = - if -- Libcrux.Kem.Kyber.validate_public_key (sz 3) -+ Libcrux.Kem.Kyber.validate_public_key #Spec.Kyber.kyber768_params (sz 3) - (sz 1152) - (sz 1184) - public_key.Libcrux.Kem.Kyber.Types.f_value -@@ -32,26 +32,8 @@ - <: - Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) - --let decapsulate_unpacked -- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 3)) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) -- = -- Libcrux.Kem.Kyber.decapsulate_unpacked (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) -- (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1120) state -- ciphertext -- - let generate_key_pair (randomness: t_Array u8 (sz 64)) = -- Libcrux.Kem.Kyber.generate_keypair (sz 3) -- (sz 1152) -- (sz 2400) -- (sz 1184) -- (sz 1152) -- (sz 2) -- (sz 128) -- randomness -- --let generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) = -- Libcrux.Kem.Kyber.generate_keypair_unpacked (sz 3) -+ Libcrux.Kem.Kyber.generate_keypair #Spec.Kyber.kyber768_params (sz 3) - (sz 1152) - (sz 2400) - (sz 1184) -diff -ruN extraction/Libcrux.Kem.Kyber.Kyber768.fsti extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti ---- extraction/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-07 18:38:45 -@@ -71,43 +71,25 @@ - unfold - let t_MlKem768PublicKey = Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184) - --/// Decapsulate ML-KEM 768 - val decapsulate - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 2400)) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -+ : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True -+ (ensures (fun res -> res == Spec.Kyber.kyber768_decapsulate secret_key.f_value ciphertext.f_value)) - --/// Encapsulate ML-KEM 768 - val encapsulate - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) - (randomness: t_Array u8 (sz 32)) - : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) - Prims.l_True -- (fun _ -> Prims.l_True) -+ (ensures (fun (ct,ss)-> (ct.f_value,ss) == Spec.Kyber.kyber768_encapsulate public_key.f_value randomness)) - --/// Validate a public key. --/// Returns `Some(public_key)` if valid, and `None` otherwise. - val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) - : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184))) - Prims.l_True - (fun _ -> Prims.l_True) - --unfold --let t_MlKem768State = Libcrux.Kem.Kyber.t_MlKemState (sz 3) -- --val decapsulate_unpacked -- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 3)) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -- --/// Generate ML-KEM 768 Key Pair - val generate_key_pair (randomness: t_Array u8 (sz 64)) - : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) - Prims.l_True -- (fun _ -> Prims.l_True) -- --val generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) -- : Prims.Pure -- (Libcrux.Kem.Kyber.t_MlKemState (sz 3) & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (ensures (fun kp -> (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.kyber768_generate_keypair randomness)) -diff -ruN extraction/Libcrux.Kem.Kyber.Matrix.fst extraction-edited/Libcrux.Kem.Kyber.Matrix.fst ---- extraction/Libcrux.Kem.Kyber.Matrix.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Matrix.fst 2024-05-07 18:38:45 -@@ -3,192 +3,188 @@ - open Core - open FStar.Mul +- let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let domain_separator, prf_input, re_as_ntt:(u8 & t_Array u8 (sz 33) & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ (prf_input: t_Array u8 (sz 33)) domain_separator = ++ let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat (wfZero) v_K ++ in ++ let orig_domain_separator = domain_separator in ++ [@ inline_let] ++ let inv: (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K) -> usize -> Type = fun acc i -> ++ let (domain_separator,prf_input,re_as_ntt) = acc in ++ if (i >=. sz 0 && i <=. v_K) ++ then ++ domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) ++ else true in ++ let (domain_separator, prf_input, re_as_ntt):(u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K)= ++ Rust_primitives.Iterators.foldi_range #_ #_ #inv { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = v_K + } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- (domain_separator, prf_input, re_as_ntt +- <: +- (u8 & t_Array u8 (sz 33) & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- ) ++ (domain_separator, prf_input, re_as_ntt) + (fun temp_0_ i -> + let domain_separator, prf_input, re_as_ntt:(u8 & t_Array u8 (sz 33) & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = + temp_0_ + in + let i:usize = i in +@@ -133,64 +134,74 @@ + Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA_RANDOMNESS_SIZE + (Rust_primitives.unsize prf_input <: t_Slice u8) + in +- let r:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA ++ let r:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1) = ++ Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA + (Rust_primitives.unsize prf_output <: t_Slice u8) + in +- let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ let r:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b r in ++ let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re_as_ntt + i + (Libcrux.Kem.Kyber.Ntt.ntt_binomially_sampled_ring_element r + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + in + domain_separator, prf_input, re_as_ntt + <: + (u8 & t_Array u8 (sz 33) & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K)) + in ++ admit(); //P-F + re_as_ntt, domain_separator + <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & u8) ++ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & u8) --let compute_As_plus_e -- (v_K: usize) -- (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +-let compress_then_serialize_u +- (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) +- (input: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) - = -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -+open Libcrux.Kem.Kyber.Arithmetic -+ -+let op_Array_Access (x:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) (i:usize{v i < 256}): i32 = -+ x.f_coefficients.[i] -+ + -+#push-options "--ifuel 0 --z3rlimit 700" -+let compute_As_plus_e v_K matrix_A s_as_ntt error_as_ntt = -+ let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in -+ let result:t_Array wfPolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat wfZero v_K - in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++let compress_then_serialize_u #p v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN input = + let out:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in ++ let orig_out = out in ++ let acc_t = t_Array u8 v_OUT_LEN in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> True in + let out:t_Array u8 v_OUT_LEN = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__iter (Rust_primitives.unsize matrix_A -- <: -- t_Slice (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- (Core.Iter.Traits.Collect.f_into_iter input - <: -- Core.Slice.Iter.t_Iter -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) - <: - Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) +- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) - <: - Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) -+ [@ inline_let] -+ let inv0 = fun (acc:t_Array wfPolynomialRingElement v_K) (i:usize) -> -+ (v i <= v v_K) /\ -+ (forall (j:usize). (v j >= v i /\ v j < v v_K) ==> (acc.[j] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) == wfZero) -+ in -+ assert (inv0 result (sz 0)); -+ let result:t_Array wfPolynomialRingElement v_K = -+ Rust_primitives.Iterators.foldi_slice #(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) #(t_Array wfPolynomialRingElement v_K) #inv0 -+ matrix_A - result - (fun result temp_1_ -> -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = result in -- let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -+ let orig_result = result in -+ let orig_result_cast = (cast_vector_b #v_K #3328 #(v v_K * 3328) orig_result) in -+ let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = - temp_1_ - in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__iter (Rust_primitives.unsize row -- <: -- t_Slice Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) ++ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #acc_t #inv ++ input + out + (fun out temp_1_ -> + let out:t_Array u8 v_OUT_LEN = out in +- let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = temp_1_ in ++ let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = temp_1_ in ++ assert (i <. v_K); ++ assert (v i + 1 <= v v_K); ++ assert (v i * (v v_OUT_LEN / v v_K) < v v_OUT_LEN); ++ assert (((v i + 1) * (v v_OUT_LEN / v v_K)) <= v v_OUT_LEN); ++ assert (v_OUT_LEN /! v_K == Spec.Kyber.v_C1_BLOCK_SIZE p); ++ assert (range (v i * v (Spec.Kyber.v_C1_BLOCK_SIZE p)) usize_inttype); ++ assert (range ((v i + 1) * v (Spec.Kyber.v_C1_BLOCK_SIZE p)) usize_inttype); ++ assert ((Core.Ops.Range.impl_index_range_slice u8 usize_inttype).f_index_pre out ++ { ++ Core.Ops.Range.f_start = i *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize; ++ Core.Ops.Range.f_end ++ = ++ (i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize ++ }); ++ assert (((i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p) -! (i *! Spec.Kyber.v_C1_BLOCK_SIZE p) == Spec.Kyber.v_C1_BLOCK_SIZE p); + Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + ({ +- Core.Ops.Range.f_start = i *! (v_OUT_LEN /! v_K <: usize) <: usize; +- Core.Ops.Range.f_end = (i +! sz 1 <: usize) *! (v_OUT_LEN /! v_K <: usize) <: usize ++ Core.Ops.Range.f_start = i *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize; ++ Core.Ops.Range.f_end = (i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize + } + <: + Core.Ops.Range.t_Range usize) + (Core.Slice.impl__copy_from_slice (out.[ { +- Core.Ops.Range.f_start = i *! (v_OUT_LEN /! v_K <: usize) <: usize; ++ Core.Ops.Range.f_start = i *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize; + Core.Ops.Range.f_end + = +- (i +! sz 1 <: usize) *! (v_OUT_LEN /! v_K <: usize) <: usize +- } - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) -- result -+ [@ inline_let] -+ let inv1 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) (inner:usize) -> -+ (v inner <= v v_K) /\ -+ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (poly_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) (v inner * 3328)) -+ in -+ assert (forall (k:usize). (v k < 256) ==> v (result.[i] <: wfPolynomialRingElement).f_coefficients.[k] == 0); -+ assert(inv1 orig_result_cast (sz 0)); -+ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = -+ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) #inv1 -+ row -+ orig_result_cast - (fun result temp_1_ -> -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- result -- in - let j, matrix_element:(usize & -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = - temp_1_ - in -- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let resulti = down_cast_poly_b #(v v_K * 3328) #(v j * 3328) result.[i] in -+ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - Libcrux.Kem.Kyber.Ntt.ntt_multiply matrix_element -- (s_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (s_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ let product_sum:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v j + 1) * 3328) = -+ (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element #(v j * 3328) #3328 v_K -+ resulti -+ product) in -+ let product_sum:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) = cast_poly_b #((v j+1)* 3328) #(v v_K * 3328) product_sum in -+ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - i -- (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K -- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- product -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ product_sum - in - result) - in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end -- = -- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -+ let result1 = result in -+ [@ inline_let] -+ let inv2 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) (inner:usize) -> -+ (v inner <= 256) /\ -+ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (forall (j:usize). (v j < v inner) ==> (i32_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)).f_coefficients.[j] 3328)) -+ // And all indexes above v inner are unchanged from result1 -+ in -+ assert (inv2 result1 (sz 0)); -+ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = -+ Rust_primitives.Iterators.foldi_range #_ #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) #inv2 { -+ Core.Ops.Range.f_start = sz 0; -+ Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -+ } - result -- (fun result j -> -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- result -- in -+ (fun result j -> -+ let result: t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = result in - let j:usize = j in -- let coefficient_normal_form:i32 = -- Libcrux.Kem.Kyber.Arithmetic.to_standard_domain ((result.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] -- <: -- i32) -+ let resulti:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) = result.[ i ] <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) in -+ let coefficient_normal_form: i32_b ((nat_div_ceil (v v_K * 3328 * 1353) (pow2 16)) + 1665) = -+ Libcrux.Kem.Kyber.Arithmetic.to_standard_domain #(v v_K * 3328) (resulti -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ]) - in -+ assert ((nat_div_ceil (v v_K * 3328 * 1353) (pow2 16)) + 1665 <= 1940); -+ let coefficient_normal_form: i32_b 1940 = cast_i32_b #((nat_div_ceil (v v_K * 3328 * 1353) (pow2 16)) + 1665) #1940 coefficient_normal_form in -+ let x1: i32_b 3328 = (error_as_ntt.[ i ] -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] in -+ let x2: i32_b 5268 = add_i32_b coefficient_normal_form x1 in -+ assert (5268 <= v v_BARRETT_R /\ v v_BARRETT_R < pow2 31); -+ let x3: i32_b (v v_BARRETT_R) = cast_i32_b #5268 #(v v_BARRETT_R) x2 in -+ let resultij: i32_b 3328 = Libcrux.Kem.Kyber.Arithmetic.barrett_reduce x3 in -+ let resultij: i32_b (v v_K * 3328) = cast_i32_b #3328 #(v v_K * 3328) resultij in -+ let resulti_coeffs = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize -+ (resulti.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) -+ j resultij in -+ let result = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - i - ({ -- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with -+ resulti with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (result.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- j -- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (coefficient_normal_form +! -- ((error_as_ntt.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] -- <: -- i32) -- <: -- i32) -- <: -- i32) -- <: -- t_Array i32 (sz 256) -+ = resulti_coeffs - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement))) -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K*3328)) in -+ assert ((result.[i]).f_coefficients.[j] == resultij); -+ assert(inv2 result (j +! sz 1)); -+ let result: x:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K{inv2 x (j +! mk_int 1)} = result in -+ result) in -+ assert (v i + 1 < v v_K ==> result.[i +! sz 1] == orig_result_cast.[i +! sz 1]); -+ let result: t_Array wfPolynomialRingElement v_K = -+ down_cast_vector_b #v_K #(v v_K * 3328) #3328 result in -+ assert (forall (j:usize). (v j >= v i + 1 /\ v j < v v_K) ==> derefine_poly_b result.[j] == derefine_poly_b orig_result.[j]); -+ assume (inv0 result (i +! sz 1)); -+ result) +- Core.Ops.Range.t_Range usize ] ++ (i +! sz 1 <: usize) *! Spec.Kyber.v_C1_BLOCK_SIZE p <: usize ++ } ] + <: + t_Slice u8) +- (Rust_primitives.unsize (Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_u ++ (Rust_primitives.unsize (Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_u #p + v_COMPRESSION_FACTOR + v_BLOCK_LEN + re +@@ -203,153 +214,168 @@ + <: + t_Array u8 v_OUT_LEN) in -- result -+ admit(); //P-F -+ result -+#pop-options ++ admit();//P-F + out --let compute_message -- (v_K: usize) -- (v: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (secret_as_ntt u_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +-let encrypt_unpacked +- (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: +- usize) +- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (a_transpose: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- (message: t_Array u8 (sz 32)) +- (randomness: t_Slice u8) - = -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+#push-options "--ifuel 0 --z3rlimit 100" -+let compute_message #p v_K m_v secret_as_ntt u_as_ntt = -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> -+ (v i <= v v_K) /\ -+ (poly_range #(v v_K * 3328) acc (v i * 3328)) -+ in -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = -+ Rust_primitives.Iterators.foldi_range #_ #acc_t #inv { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- result -+ result - (fun result i -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in - let i:usize = i in -- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let result:t_PolynomialRingElement_b (v i * 3328) = -+ down_cast_poly_b #(v v_K * 3328) #(v i * 3328) result in -+ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - Libcrux.Kem.Kyber.Ntt.ntt_multiply (secret_as_ntt.[ i ] - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (u_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (u_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v i+1) * 3328) = - Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K result product - in -+ let result = cast_poly_b #((v i + 1) * 3328) #(v v_K * 3328) result in -+ assert(inv result (i +! sz 1)); - result) - in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K result -+ let acc_t = t_PolynomialRingElement_b (64*v v_K*3328) in -+ let result:acc_t = Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K result - in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> -+ (v i <= 256) /\ -+ (forall (j:usize). (v j < v i) ==> i32_range ((acc <: t_PolynomialRingElement_b (64* v v_K * 3328)).f_coefficients.[j]) 3328) in -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K*3328) = -+ Rust_primitives.Iterators.foldi_range #_ #_ #inv { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT - } +- let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = into_padded_array (sz 33) randomness in +- let r_as_ntt, domain_separator:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- u8) = +- sample_vector_cbd_then_ntt v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy +- in +- let tmp0, tmp1, out:(t_Array u8 (sz 33) & u8 & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = +- sample_ring_element_cbd v_K v_ETA2_RANDOMNESS_SIZE v_ETA2 prf_input domain_separator +- in +- let prf_input:t_Array u8 (sz 33) = tmp0 in +- let domain_separator:u8 = tmp1 in +- let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = out in +- let prf_input:t_Array u8 (sz 33) = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_input (sz 32) domain_separator +- in +- let (prf_output: t_Array u8 v_ETA2_RANDOMNESS_SIZE):t_Array u8 v_ETA2_RANDOMNESS_SIZE = +- Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE +- (Rust_primitives.unsize prf_input <: t_Slice u8) +- in +- let error_2_:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA2 +- (Rust_primitives.unsize prf_output <: t_Slice u8) +- in +- let u:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Libcrux.Kem.Kyber.Matrix.compute_vector_u v_K a_transpose r_as_ntt error_1_ +- in +- let message_as_ring_element:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_message message +- in +- let v:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Matrix.compute_ring_element_v v_K +- tt_as_ntt +- r_as_ntt +- error_2_ +- message_as_ring_element +- in +- let c1:t_Array u8 v_C1_LEN = +- compress_then_serialize_u v_K v_C1_LEN v_U_COMPRESSION_FACTOR v_BLOCK_LEN u +- in +- let c2:t_Array u8 v_C2_LEN = +- Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_v v_V_COMPRESSION_FACTOR +- v_C2_LEN +- v +- in +- let (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE):t_Array u8 v_CIPHERTEXT_SIZE = +- into_padded_array v_CIPHERTEXT_SIZE (Rust_primitives.unsize c1 <: t_Slice u8) +- in +- let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from ciphertext +- ({ Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize) +- (Core.Slice.impl__copy_from_slice (ciphertext.[ { Core.Ops.Range.f_start = v_C1_LEN } +- <: +- Core.Ops.Range.t_RangeFrom usize ] - <: -- Core.Ops.Range.t_Range usize) +- t_Slice u8) +- (Core.Array.impl_23__as_slice v_C2_LEN c2 <: t_Slice u8) - <: -- Core.Ops.Range.t_Range usize) -- result -+ result - (fun result i -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in - let i:usize = i in -- let coefficient_normal_form:i32 = -- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) *! -- 1441l -- <: -- i32) -- in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- { -- result with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- i -- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((v -+ let coefficient_normal_form: i32_b (nat_div_ceil (306921472*v v_K) 65536 + 1665) = -+ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce -+ (Libcrux.Kem.Kyber.Arithmetic.mul_i32_b #(64 * v v_K * 3328) #1441 -+ result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -+ (1441l <: Libcrux.Kem.Kyber.Arithmetic.i32_b 1441)) in -+ let resulti : i32_b 3328 = (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((m_v - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] - <: - i32) -! -@@ -196,81 +192,77 @@ +- t_Slice u8) +- in +- ciphertext +- +-let deserialize_then_decompress_u +- (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) +- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- = +- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize ciphertext <: t_Slice u8) +- ((Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! ++#push-options "--split_queries always" ++let deserialize_then_decompress_u (#p:Spec.Kyber.params) ++ (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR: usize) ++ (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = ++ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat wfZero v_K ++ in ++ let acc_t1 = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in ++ [@ inline_let] ++ let inv = fun (acc:acc_t1) (i:usize) -> True in ++ let sl : t_Slice u8 = ciphertext.[ ++ { Core.Ops.Range.f_end = v_VECTOR_U_ENCODED_SIZE } <: Core.Ops.Range.t_RangeTo usize ] in ++ assert (length sl == v_VECTOR_U_ENCODED_SIZE); ++ let chunk_len = ((Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! + v_U_COMPRESSION_FACTOR <: - i32) - <: -- i32) -+ i32) in -+ let resulti = cast_i32_b #3328 #(64*v v_K*3328) resulti in -+ let result = -+ { -+ result with -+ Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ i resulti - } + usize) /! + sz 8 + <: +- usize) +- <: +- Core.Slice.Iter.t_ChunksExact u8) - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ usize) in ++ FStar.Math.Lemmas.cancel_mul_mod (v p.v_RANK) (v (Spec.Kyber.v_C1_BLOCK_SIZE p)) ; ++ assert (v chunk_len == v (Spec.Kyber.v_C1_BLOCK_SIZE p)); ++ assert (Seq.length sl % v (Spec.Kyber.v_C1_BLOCK_SIZE p) = 0); ++ assert (Seq.length sl == v (Spec.Kyber.v_C1_SIZE p)); ++ assert (Seq.length sl / v (Spec.Kyber.v_C1_BLOCK_SIZE p) == v v_K); ++ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t1 #inv ++ sl ++ chunk_len + u_as_ntt + (fun u_as_ntt temp_1_ -> +- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = + u_as_ntt in -+ assert (inv result (i +! sz 1)); - result) +- let i, u_bytes:(usize & t_Slice u8) = temp_1_ in +- let u:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let i, u_bytes:(usize & t_Array u8 chunk_len) = temp_1_ in ++ let u:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_ring_element_u v_U_COMPRESSION_FACTOR + u_bytes + in +- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ assert (v i < v v_K); ++ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize u_as_ntt + i + (Libcrux.Kem.Kyber.Ntt.ntt_vector_u v_U_COMPRESSION_FACTOR u + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + in + u_as_ntt) in + admit(); //P-F - result + u_as_ntt +#pop-options --let compute_ring_element_v -- (v_K: usize) -- (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- (error_2_ message: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- = -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+#push-options "--ifuel 0 --z3rlimit 100" -+let compute_ring_element_v v_K tt_as_ntt r_as_ntt error_2_ message = -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +-let decrypt_unpacked ++#push-options "--z3rlimit 200" ++let deserialize_public_key (#p:Spec.Kyber.params) ++ (v_K: usize) (public_key: t_Slice u8) = ++ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat wfZero v_K ++ in ++ let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in + [@ inline_let] -+ let inv = fun (acc:t_PolynomialRingElement_b (v v_K * 3328)) (i:usize) -> -+ (v i <= 256) /\ -+ (poly_range acc (v i * 3328)) in -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = -+ Rust_primitives.Iterators.foldi_range #_ #_ #inv ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } -- <: -- Core.Ops.Range.t_Range usize) - <: - Core.Ops.Range.t_Range usize) - result - (fun result i -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- let i:usize = i in -- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - Libcrux.Kem.Kyber.Ntt.ntt_multiply (tt_as_ntt.[ i ] - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (r_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (r_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let result:t_PolynomialRingElement_b (v i * 3328) = -+ down_cast_poly_b #(v v_K * 3328) #(v i * 3328) result in -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v i + 1) * 3328) = - Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K result product - in -- result) -+ cast_poly_b result) ++ let inv = fun (acc:acc_t) (i:usize) -> True in ++ let chunk_len = Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT in ++ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv ++ public_key ++ chunk_len ++ tt_as_ntt ++ (fun tt_as_ntt temp_1_ -> ++ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ tt_as_ntt ++ in ++ let i, tt_as_ntt_bytes:(usize & t_Array u8 chunk_len) = temp_1_ in ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize tt_as_ntt ++ i ++ (Libcrux.Kem.Kyber.Serialize.deserialize_to_uncompressed_ring_element tt_as_ntt_bytes ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ <: ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ in ++ admit(); //P-F ++ tt_as_ntt ++#pop-options ++ ++#push-options "--split_queries always" ++let deserialize_secret_key (#p:Spec.Kyber.params) (v_K: usize) (secret_key: t_Slice u8) = ++ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat wfZero v_K ++ in ++ let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> True in ++ let sl : t_Slice u8 = secret_key in ++ let chunk_len = Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT in ++ assert(v chunk_len == 384); ++ assert(Seq.length secret_key == v (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)); ++ assert(Seq.length secret_key == (v v_K * 256 * 12)/8); ++ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv ++ sl ++ chunk_len ++ secret_as_ntt ++ (fun secret_as_ntt temp_1_ -> ++ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ secret_as_ntt ++ in ++ let i, secret_bytes:(usize & t_Array u8 chunk_len) = temp_1_ in ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt ++ i ++ (Libcrux.Kem.Kyber.Serialize.deserialize_to_uncompressed_ring_element secret_bytes ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ <: ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ in ++ admit(); //P-F ++ secret_as_ntt ++#pop-options ++ ++#push-options "--z3rlimit 400 --split_queries no" ++let decrypt #p + (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: + usize) +- (secret_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- = +- let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- deserialize_then_decompress_u v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR ciphertext ++ (secret_key: t_Slice u8) ++ (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = ++ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ deserialize_then_decompress_u #p v_K ++ v_CIPHERTEXT_SIZE ++ v_VECTOR_U_ENCODED_SIZE ++ v_U_COMPRESSION_FACTOR ++ ciphertext in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) = - Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K result +- let v:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_ring_element_v v_V_COMPRESSION_FACTOR ++ let v:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_ring_element_v #p v_V_COMPRESSION_FACTOR + (ciphertext.[ { Core.Ops.Range.f_start = v_VECTOR_U_ENCODED_SIZE } + <: + Core.Ops.Range.t_RangeFrom usize ] + <: + t_Slice u8) in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ [@ inline_let] -+ let inv = fun (acc:t_PolynomialRingElement_b (64 * v v_K * 3328)) (i:usize) -> -+ (v i <= 256) /\ -+ (forall (j:usize). (v j < v i) ==> i32_range ((acc <: t_PolynomialRingElement_b (64* v v_K * 3328)).f_coefficients.[j]) 3328) in -+ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) = -+ Rust_primitives.Iterators.foldi_range #_ #_ #inv { - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT - } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- result -+ result - (fun result i -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- let i:usize = i in -- let coefficient_normal_form:i32 = -- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) *! -- 1441l -- <: -- i32) -- in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- { -- result with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- i -- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((coefficient_normal_form +! -+ let coefficient_normal_form: i32_b (nat_div_ceil (306921472*v v_K) 65536 + 1665) = -+ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce -+ (Libcrux.Kem.Kyber.Arithmetic.mul_i32_b #(64 * v v_K * 3328) #1441 -+ result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -+ (1441l <: Libcrux.Kem.Kyber.Arithmetic.i32_b 1441)) in -+ let resulti : i32_b 3328 = -+ (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((coefficient_normal_form +! - (error_2_.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] <: i32) - <: - i32) +! -@@ -278,157 +270,151 @@ - <: - i32) - <: -- i32) -+ i32) in -+ let resulti = cast_i32_b #3328 #(64*v v_K*3328) resulti in -+ let result = -+ { -+ result with -+ Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ i resulti - } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement - in - result) +- let message:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Matrix.compute_message v_K v secret_as_ntt u_as_ntt ++ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ deserialize_secret_key #p v_K secret_key in -+ admit(); //P-F - result +- Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message +- +-let encrypt +- (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: +- usize) +- (public_key: t_Slice u8) ++ let message:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Matrix.compute_message #p v_K v secret_as_ntt u_as_ntt ++ in ++ let res = Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message in ++ res +#pop-options - -+#push-options "--ifuel 0 --z3rlimit 300" - let compute_vector_u - (v_K: usize) -- (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ ++#push-options "--z3rlimit 200" ++let encrypt #p ++ v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE ++ public_key + (message: t_Array u8 (sz 32)) +- (randomness: t_Slice u8) - = -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -+ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) -+ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = -+ let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in -+ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat wfZero v_K +- let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Libcrux.Kem.Kyber.Serialize.deserialize_ring_elements_reduced v_T_AS_NTT_ENCODED_SIZE +- v_K ++ (randomness: t_Slice u8) = ++ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ deserialize_public_key #p v_K + (public_key.[ { Core.Ops.Range.f_end = v_T_AS_NTT_ENCODED_SIZE } + <: + Core.Ops.Range.t_RangeTo usize ] +@@ -361,82 +387,98 @@ + <: + Core.Ops.Range.t_RangeFrom usize ] in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- let a_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- Libcrux.Kem.Kyber.Matrix.sample_matrix_A v_K ++ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = ++ Libcrux.Kem.Kyber.Matrix.sample_matrix_A #p v_K + (into_padded_array (sz 34) seed <: t_Array u8 (sz 34)) + false + in +- encrypt_unpacked v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN +- v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 +- v_ETA2_RANDOMNESS_SIZE tt_as_ntt a_transpose message randomness +- +-let deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) = +- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__iter (Rust_primitives.unsize a_as_ntt -- <: -- t_Slice (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- (Core.Slice.impl__chunks_exact secret_key +- Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT - <: -- Core.Slice.Iter.t_Iter -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) -+ let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in -+ [@ inline_let] -+ let inv0 = fun (acc:t_Array wfPolynomialRingElement v_K) (i:usize) -> -+ (v i <= v v_K) /\ -+ (forall (j:usize). (v j >= v i /\ v j < v v_K) ==> (acc.[j] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) == wfZero) +- Core.Slice.Iter.t_ChunksExact u8) ++ let (prf_input: t_Array u8 (sz 33)):t_Array u8 (sz 33) = into_padded_array (sz 33) randomness in ++ let r_as_ntt, domain_separator:(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & ++ u8) = ++ sample_vector_cbd_then_ntt #p v_K v_ETA1 v_ETA1_RANDOMNESS_SIZE prf_input 0uy + in -+ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Rust_primitives.Iterators.foldi_slice #(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) #acc_t #inv0 -+ a_as_ntt - result - (fun result temp_1_ -> -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = result in -- let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = -+ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = result in -+ let orig_result = result in -+ let orig_result_cast = (cast_vector_b #v_K #3328 #(64 * v v_K * 3328) orig_result) in -+ let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = - temp_1_ - in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__iter (Rust_primitives.unsize row -- <: -- t_Slice Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate -- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) -- result -+ [@ inline_let] -+ let inv1 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K) (inner:usize) -> -+ (v inner <= v v_K) /\ -+ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (poly_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) (v inner * 3328)) -+ in -+ assert (forall (k:usize). (v k < 256) ==> v (result.[i] <: wfPolynomialRingElement).f_coefficients.[k] == 0); -+ assert(inv1 orig_result_cast (sz 0)); -+ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K = -+ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K) #inv1 -+ row -+ orig_result_cast - (fun result temp_1_ -> -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- result -- in -- let j, a_element:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let j, a_element:(usize & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = - temp_1_ - in -- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let resulti = down_cast_poly_b #(64 * v v_K * 3328) #(v j * 3328) result.[i] in -+ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - Libcrux.Kem.Kyber.Ntt.ntt_multiply a_element -- (r_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (r_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ let product_sum:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v j + 1) * 3328) = -+ (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element #(v j * 3328) #3328 v_K -+ resulti -+ product) in -+ let product_sum:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) = cast_poly_b #((v j+1)* 3328) #(64 * v v_K * 3328) product_sum in -+ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - i -- (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K -- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- product -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ product_sum - in - result) - in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ assert (forall (j:usize). (v j < v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); -+ assert (forall (j:usize). (v j > v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); -+ let resulti : t_PolynomialRingElement_b (v v_K * 3328) = down_cast_poly_b result.[i] in -+ let result = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - i -- (Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K -- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K resulti) -+ in -+ [@ inline_let] -+ let inv2 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K) (inner:usize) -> -+ (v inner <= 256) /\ -+ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ -+ (forall (j:usize). (v j < v inner) ==> (i32_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)).f_coefficients.[j] 3328)) -+ // And all indexes above v inner are unchanged from result1 - in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end -- = -- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- } -- <: -- Core.Ops.Range.t_Range usize) ++ assert (v domain_separator == v v_K); ++ let tmp0, tmp1, out:(t_Array u8 (sz 33) & u8 & ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = ++ sample_vector_cbd #p v_K v_ETA2_RANDOMNESS_SIZE v_ETA2 prf_input domain_separator ++ in ++ let prf_input:t_Array u8 (sz 33) = tmp0 in ++ let domain_separator:u8 = tmp1 in ++ let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = out in ++ let prf_input:t_Array u8 (sz 33) = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize prf_input (sz 32) domain_separator ++ in ++ assert (Seq.equal prf_input (Seq.append randomness (Seq.create 1 domain_separator))); ++ assert (prf_input == Seq.append randomness (Seq.create 1 domain_separator)); ++ let (prf_output: t_Array u8 v_ETA2_RANDOMNESS_SIZE):t_Array u8 v_ETA2_RANDOMNESS_SIZE = ++ Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE ++ (Rust_primitives.unsize prf_input <: t_Slice u8) ++ in ++ let error_2_:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1) = ++ Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA2 ++ (Rust_primitives.unsize prf_output <: t_Slice u8) ++ in ++ let error_2_:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b error_2_ in ++ let u:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Libcrux.Kem.Kyber.Matrix.compute_vector_u #p v_K v_A_transpose r_as_ntt error_1_ ++ in ++ let message_as_ring_element:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Serialize.deserialize_then_decompress_message message ++ in ++ let v:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Matrix.compute_ring_element_v #p v_K ++ tt_as_ntt ++ r_as_ntt ++ error_2_ ++ message_as_ring_element ++ in ++ let c1:t_Array u8 v_C1_LEN = ++ compress_then_serialize_u #p v_K v_C1_LEN v_U_COMPRESSION_FACTOR v_BLOCK_LEN u ++ in ++ let c2:t_Array u8 v_C2_LEN = ++ Libcrux.Kem.Kyber.Serialize.compress_then_serialize_ring_element_v #p v_V_COMPRESSION_FACTOR ++ v_C2_LEN ++ v ++ in ++ assert (v_C1_LEN = Spec.Kyber.v_C1_SIZE p); ++ assert (v_C2_LEN = Spec.Kyber.v_C2_SIZE p); ++ assert (v_CIPHERTEXT_SIZE == v_C1_LEN +! v_C2_LEN); ++ assert (v_C1_LEN <=. v_CIPHERTEXT_SIZE); ++ let (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE):t_Array u8 v_CIPHERTEXT_SIZE = ++ into_padded_array v_CIPHERTEXT_SIZE (Rust_primitives.unsize c1 <: t_Slice u8) ++ in ++ let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from ciphertext ++ ({ Core.Ops.Range.f_start = v_C1_LEN } <: Core.Ops.Range.t_RangeFrom usize) ++ (Core.Slice.impl__copy_from_slice (ciphertext.[ { Core.Ops.Range.f_start = v_C1_LEN } ++ <: ++ Core.Ops.Range.t_RangeFrom usize ] + <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ t_Slice u8) ++ (Core.Array.impl_23__as_slice v_C2_LEN c2 <: t_Slice u8) + <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- secret_as_ntt +- (fun secret_as_ntt temp_1_ -> +- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- secret_as_ntt +- in +- let i, secret_bytes:(usize & t_Slice u8) = temp_1_ in +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt +- i +- (Libcrux.Kem.Kyber.Serialize.deserialize_to_uncompressed_ring_element secret_bytes - <: -- Core.Ops.Range.t_Range usize) -+ assert (forall (j:usize). (v j < v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); -+ assert (forall (j:usize). (v j > v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); -+ assert (inv2 result (sz 0)); -+ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K = -+ Rust_primitives.Iterators.foldi_range #_ #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K) #inv2 { -+ Core.Ops.Range.f_start = sz 0; -+ Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -+ } - result - (fun result j -> -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- result -- in -- let j:usize = j in -- let coefficient_normal_form:i32 = -- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (((result.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] -- <: -- i32) *! -- 1441l -- <: -- i32) -- in -- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ let result: t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K = result in -+ let resulti:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) = result.[ i ] <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) in -+ let coefficient_normal_form: i32_b (nat_div_ceil (306921472*v v_K) 65536 + 1665) = -+ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce -+ (Libcrux.Kem.Kyber.Arithmetic.mul_i32_b #(64 * v v_K * 3328) #1441 -+ (resulti <: t_PolynomialRingElement_b (64*v v_K * 3328)).f_coefficients.[j] (1441l <: Libcrux.Kem.Kyber.Arithmetic.i32_b 1441)) in -+ let resultij: i32_b 3328 = (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce -+ (add_i32_b coefficient_normal_form ((error_1_.[ i ] -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ]))) in -+ let result = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result - i - ({ -- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with -+ resulti with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients - = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (result.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (resulti -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients) - j -- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (coefficient_normal_form +! -- ((error_1_.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] -- <: -- i32) -- <: -- i32) -- <: -- i32) -- <: -- t_Array i32 (sz 256) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- in -- result)) -+ (cast_i32_b #3328 #(64 * v v_K * 3328) resultij) -+ }) in -+ result) -+ in -+ let result: t_Array wfPolynomialRingElement v_K = -+ down_cast_vector_b #v_K #(64 * v v_K * 3328) #3328 result in -+ assert (forall (j:usize). (v j >= v i + 1 /\ v j < v v_K) ==> derefine_poly_b result.[j] == derefine_poly_b orig_result.[j]); -+ assume (inv0 result (i +! sz 1)); -+ result) +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ t_Slice u8) in -+ admit(); //P-F - result +- secret_as_ntt +- +-let decrypt +- (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: +- usize) +- (secret_key: t_Slice u8) +- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- = +- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- deserialize_secret_key v_K secret_key +- in +- decrypt_unpacked v_K +- v_CIPHERTEXT_SIZE +- v_VECTOR_U_ENCODED_SIZE +- v_U_COMPRESSION_FACTOR +- v_V_COMPRESSION_FACTOR +- secret_as_ntt +- ciphertext ++ lemma_slice_append ciphertext c1 c2; ++ ciphertext +#pop-options - let sample_matrix_A (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) = -- let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -- Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -- v_K +-let serialize_secret_key ++let serialize_secret_key (#p:Spec.Kyber.params) + (v_K v_OUT_LEN: usize) +- (key: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- = ++ (key: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = + let out:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in ++ let orig_out = out in ++ let acc_t = t_Array u8 v_OUT_LEN in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> True in + let out:t_Array u8 v_OUT_LEN = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Iter.Traits.Collect.f_into_iter key +- <: +- Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) - <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- v_K -+ let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in -+ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = -+ Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat wfZero v_K) v_K - in -- let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -+ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K -@@ -440,7 +426,7 @@ - v_A_transpose - (fun v_A_transpose i -> - let v_A_transpose:t_Array -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -+ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = - v_A_transpose - in - let i:usize = i in -@@ -482,8 +468,8 @@ - in - seeds) - in -- let sampled:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Libcrux.Kem.Kyber.Sampling.sample_from_xof v_K seeds -+ let xof_bytes:t_Array (t_Array u8 (sz 840)) v_K = -+ Libcrux.Kem.Kyber.Hash_functions.v_XOFx4 v_K seeds - in - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; -@@ -496,40 +482,46 @@ - v_A_transpose - (fun v_A_transpose j -> - let v_A_transpose:t_Array -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -+ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = - v_A_transpose - in - let j:usize = j in -+ let sampled:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Sampling.sample_from_uniform_distribution (xof_bytes.[ j ] -+ <: -+ t_Array u8 (sz 840)) -+ in - if transpose - then - let v_A_transpose:t_Array -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -+ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v_A_transpose - j - (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (v_A_transpose.[ j - ] - <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) - i -- (sampled.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ sampled - <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) - in - v_A_transpose - else - let v_A_transpose:t_Array -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -+ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v_A_transpose - i - (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (v_A_transpose.[ i - ] - <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) - j -- (sampled.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ sampled - <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) - in - v_A_transpose)) +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Array.Iter.t_IntoIter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) ++ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #acc_t #inv ++ key + out + (fun out temp_1_ -> + let out:t_Array u8 v_OUT_LEN = out in +- let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = temp_1_ in ++ let i, re:(usize & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = temp_1_ in + Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + ({ + Core.Ops.Range.f_start +@@ -475,13 +517,14 @@ + <: + t_Array u8 v_OUT_LEN) in + admit(); //P-F - v_A_transpose -diff -ruN extraction/Libcrux.Kem.Kyber.Matrix.fsti extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti ---- extraction/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-07 18:38:45 -@@ -3,46 +3,71 @@ - open Core - open FStar.Mul + out --/// Compute  ◦ ŝ + ê --val compute_As_plus_e +-let serialize_public_key + -+val compute_As_plus_e (#p:Spec.Kyber.params) - (v_K: usize) -- (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) -+ (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (requires (v_K == p.v_RANK)) -+ (ensures fun res -> -+ let open Libcrux.Kem.Kyber.Arithmetic in -+ v_K == p.v_RANK /\ -+ to_spec_vector_b #p res = -+ Spec.Kyber.compute_As_plus_e #p -+ (to_spec_matrix_b #p matrix_A) -+ (to_spec_vector_b #p s_as_ntt) -+ (to_spec_vector_b #p error_as_ntt)) ++let serialize_public_key (#p:Spec.Kyber.params) + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) +- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (seed_for_a: t_Slice u8) +- = ++ (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (seed_for_a: t_Slice u8) = + let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = + Rust_primitives.Hax.repeat 0uy v_PUBLIC_KEY_SIZE + in +@@ -498,7 +541,7 @@ + Core.Ops.Range.t_Range usize ] + <: + t_Slice u8) +- (Rust_primitives.unsize (serialize_secret_key v_K ++ (Rust_primitives.unsize (serialize_secret_key #p v_K + v_RANKED_BYTES_PER_RING_ELEMENT + tt_as_ntt + <: +@@ -524,232 +567,49 @@ + <: + t_Slice u8) + in ++ lemma_slice_append public_key_serialized ++ (Spec.Kyber.vector_encode_12 (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p tt_as_ntt)) ++ seed_for_a; + public_key_serialized --/// The following functions compute various expressions involving --/// vectors and matrices. The computation of these expressions has been --/// abstracted away into these functions in order to save on loop iterations. --/// Compute v − InverseNTT(sᵀ ◦ NTT(u)) --val compute_message +-let generate_keypair_unpacked +- (v_K v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) +- (key_generation_seed: t_Slice u8) +- = + -+val compute_message (#p:Spec.Kyber.params) - (v_K: usize) -- (v: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (secret_as_ntt u_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (poly_v: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (secret_as_ntt u_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires (v_K == p.v_RANK)) -+ (ensures (fun res -> -+ let secret_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p secret_as_ntt in -+ let u_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p u_as_ntt in -+ let v_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b poly_v in -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res == -+ Spec.Kyber.(poly_sub v_spec (poly_inv_ntt #p (vector_dot_product secret_spec u_spec))))) - --/// Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message --val compute_ring_element_v -+// TODO: error_2_ changed from `t_PolynomialRingElement_b 3` to `t_PolynomialRingElement_b 7` -+val compute_ring_element_v (#p:Spec.Kyber.params) - (v_K: usize) -- (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- (error_2_ message: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (error_2_: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7) -+ (message: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires (v_K == p.v_RANK)) -+ (ensures fun res -> -+ let tt_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p tt_as_ntt in -+ let r_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p r_as_ntt in -+ let e2_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b error_2_ in -+ let m_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b message in -+ let res_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res in -+ res_spec == Spec.Kyber.(poly_add (poly_add (vector_dot_product tt_spec r_spec) e2_spec) m_spec)) - --/// Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ --val compute_vector_u -+val compute_vector_u (#p:Spec.Kyber.params) - (v_K: usize) -- (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) -+ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) -+ (requires (v_K == p.v_RANK)) -+ (ensures fun res -> -+ let a_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p a_as_ntt in -+ let r_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p r_as_ntt in -+ let e_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p error_1_ in -+ let res_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res in -+ res_spec == Spec.Kyber.(vector_add (vector_inv_ntt (matrix_vector_mul a_spec r_spec)) e_spec)) - --val sample_matrix_A (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) -- : Prims.Pure (t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ -+ -+val sample_matrix_A (#p:Spec.Kyber.params) (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) -+ : Pure (t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) -+ (requires (v_K == p.v_RANK)) -+ (ensures fun res -> -+ let matrix_A = Spec.Kyber.sample_matrix_A #p (Seq.slice seed 0 32) in -+ if transpose then Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p res == matrix_A -+ else Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p res == Spec.Kyber.matrix_transpose matrix_A) -diff -ruN extraction/Libcrux.Kem.Kyber.Ntt.fst extraction-edited/Libcrux.Kem.Kyber.Ntt.fst ---- extraction/Libcrux.Kem.Kyber.Ntt.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Ntt.fst 2024-05-07 18:38:45 -@@ -1,56 +1,130 @@ - module Libcrux.Kem.Kyber.Ntt --#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" - open Core - open FStar.Mul - --let ntt_multiply_binomials (a0, a1: (i32 & i32)) (b0, b1: (i32 & i32)) (zeta: i32) = -- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b0 <: i32) +! -- ((Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (a1 *! b1 <: i32) <: i32) *! zeta <: i32) -- <: -- i32), -- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b1 <: i32) +! (a1 *! b0 <: i32) <: i32) -- <: -- (i32 & i32) - --let invert_ntt_at_layer -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer: usize) -- = -+let v_ZETAS_TIMES_MONTGOMERY_R = -+ let list : list (i32_b 1664) = -+ [ -+ (-1044l); (-758l); (-359l); (-1517l); 1493l; 1422l; 287l; 202l; (-171l); 622l; 1577l; 182l; -+ 962l; (-1202l); (-1474l); 1468l; 573l; (-1325l); 264l; 383l; (-829l); 1458l; (-1602l); (-130l); -+ (-681l); 1017l; 732l; 608l; (-1542l); 411l; (-205l); (-1571l); 1223l; 652l; (-552l); 1015l; -+ (-1293l); 1491l; (-282l); (-1544l); 516l; (-8l); (-320l); (-666l); (-1618l); (-1162l); 126l; -+ 1469l; (-853l); (-90l); (-271l); 830l; 107l; (-1421l); (-247l); (-951l); (-398l); 961l; -+ (-1508l); (-725l); 448l; (-1065l); 677l; (-1275l); (-1103l); 430l; 555l; 843l; (-1251l); 871l; -+ 1550l; 105l; 422l; 587l; 177l; (-235l); (-291l); (-460l); 1574l; 1653l; (-246l); 778l; 1159l; -+ (-147l); (-777l); 1483l; (-602l); 1119l; (-1590l); 644l; (-872l); 349l; 418l; 329l; (-156l); -+ (-75l); 817l; 1097l; 603l; 610l; 1322l; (-1285l); (-1465l); 384l; (-1215l); (-136l); 1218l; -+ (-1335l); (-874l); 220l; (-1187l); (-1659l); (-1185l); (-1530l); (-1278l); 794l; (-1510l); -+ (-854l); (-870l); 478l; (-108l); (-308l); 996l; 991l; 958l; (-1460l); 1522l; 1628l -+ ] -+ in -+ FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 128); -+ FStar.Pervasives.assert_norm (List.Tot.index list 1 == -758l); -+ Seq.of_list list -+ -+open Libcrux.Kem.Kyber.Arithmetic -+ -+#push-options "--z3rlimit 50" -+let ntt_multiply_binomials (a0,a1) (b0,b1) zeta = -+ let r0 = montgomery_reduce (mul_i32_b a1 b1) in -+ let res = -+ montgomery_reduce (add_i32_b (mul_i32_b a0 b0) (mul_i32_b r0 zeta)), -+ montgomery_reduce (add_i32_b (mul_i32_b a0 b1) (mul_i32_b a1 b0)) in -+ res -+#pop-options -+ -+val mul_zeta_red (#v_K:usize{v v_K >= 1 /\ v v_K <= 4}) -+ (#b:nat{b <= v v_K * 3328 * 64}) -+ (zeta_i:usize{v zeta_i > 0 /\ v zeta_i <= 128} ) -+ (layer:usize{v layer > 0 /\ -+ v layer <= 7 /\ -+ v zeta_i == pow2 (8 - v layer) /\ -+ b == v v_K * 3328 * pow2(v layer - 1)}) -+ (x:i32_b (2*b)) -+ (i:usize{v i < 128 / pow2 (v layer)}) : -+ i32_b (2*b) -+let mul_zeta_red #v_K #b zeta_i layer x i = -+ let zeta_i = zeta_i -! sz 1 -! i in -+ let zeta:i32_b 1664 = v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] in -+ if layer <=. sz 6 then ( -+ assert (b <= 4 * 3328 * 32); -+ assert (2*b*1664 < pow2 31); -+ let product:i32_b (2 * b * 1664) = mul_i32_b x zeta in -+ let res = montgomery_reduce product in -+ res -+ ) else ( -+ assert (v i < 1); -+ assert (zeta_i = sz 1); -+ assert (zeta = -758l); -+ let zeta:i32_b 758 = zeta in -+ let product:i32_b (2 * b * 758) = mul_i32_b x zeta in -+ let res = montgomery_reduce product in -+ res -+ ) -+ -+ -+val lemma_zeta_decr: orig:usize -> fin:usize -> layer:usize{v layer <= 7} -> -+ Lemma (v fin == v orig - 128/(pow2 (v layer)) /\ -+ v orig == pow2 (8 - v layer) ==> -+ v fin == pow2 (7 - v layer)) -+let lemma_zeta_decr orig fin layer = () -+ -+#push-options "--ifuel 0 --z3rlimit 1200" -+let invert_ntt_at_layer #v_K #b zeta_i re layer = - let step:usize = sz 1 < 0); -+ assert (v step == pow2 (v layer)); -+ let orig_re = re in -+ let orig_zeta_i = zeta_i in -+ [@ inline_let] -+ let inv = fun (acc:t_PolynomialRingElement_b (2*b) & usize) (i:usize) -> -+ let (re,zeta_i) = acc in -+ v zeta_i == v orig_zeta_i - v i /\ -+ (forall k. (v k >= 2 * v i * v step (* + 2 * v step *)) ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]) -+ in -+ let re, zeta_i: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) & usize) = -+ Rust_primitives.Iterators.foldi_range #_ #(t_PolynomialRingElement_b (2*b) & usize) #inv { - Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = sz 128 >>! layer <: usize -+ Core.Ops.Range.f_end = sz 128 /! step - } +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = v_K +- } - <: - Core.Ops.Range.t_Range usize) - <: - Core.Ops.Range.t_Range usize) -- (re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) -+ (cast_poly_b #b #(2*b) re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) & usize)) - (fun temp_0_ round -> -- let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize) = temp_0_ in -+ let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) & usize) = temp_0_ in - let round:usize = round in -+ let orig_re_round = re in - let zeta_i:usize = zeta_i -! sz 1 in -- let offset:usize = (round *! step <: usize) *! sz 2 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ assert(v round * v step < 128); -+ assert(v round * v step + v step <= 128); -+ assert(v round * v step * 2 <= 254); -+ assert(v round * v step * 2 + 2 * v step <= 256); -+ let offset:usize = (round *! step) *! sz 2 in -+ assert (v offset + 2 * v step <= 256); -+ assert (v offset + v step <= 256); -+ assert (forall k. v k >= v offset ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]); -+ [@ inline_let] -+ let inv = fun (acc:t_PolynomialRingElement_b (2 * b)) (i:usize) -> -+ (forall k. (v k >= v i /\ v k < v offset + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) /\ -+ (forall k. (v k >= v i + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) -+ in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) = -+ Rust_primitives.Iterators.foldi_range #_ #_ #inv { - Core.Ops.Range.f_start = offset; - Core.Ops.Range.f_end = offset +! step <: usize -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -+ } - re - (fun re j -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) = re in -+ assert (re.f_coefficients.[j] == orig_re_round.f_coefficients.[j]); -+ assert (re.f_coefficients.[j +! step] == orig_re_round.f_coefficients.[j +! step]); -+ assert (re.f_coefficients.[j] == orig_re.f_coefficients.[j]); -+ assert (re.f_coefficients.[j +! step] == orig_re.f_coefficients.[j +! step]); -+ let re_j:i32_b b = orig_re.f_coefficients.[j] in -+ let re_j_step:i32_b b = orig_re.f_coefficients.[j +! step] in - let j:usize = j in -- let a_minus_b:i32 = -- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! step <: usize ] <: i32) -! -- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) -- in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let a_minus_b:i32_b (2*b) = sub_i32_b re_j_step re_j in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -58,17 +132,13 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - j -- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +! -- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! step <: usize ] -- <: -- i32) -- <: -- i32) -+ (add_i32_b re_j re_j_step) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let red = mul_zeta_red #v_K #b orig_zeta_i layer a_minus_b round in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -76,67 +146,69 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (j +! step <: usize) -- (Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (a_minus_b *! -- (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) -- <: -- i32) +- (secret_as_ntt, tt_as_ntt +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- (fun temp_0_ i -> +- let secret_as_ntt, tt_as_ntt:(t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = +- temp_0_ +- in +- let i:usize = i in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end +- = +- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- (secret_as_ntt, tt_as_ntt +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- (fun temp_0_ j -> +- let secret_as_ntt, tt_as_ntt:(t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = +- temp_0_ +- in +- let j:usize = j in +- let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize secret_as_ntt +- i +- ({ +- (secret_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- ) with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (secret_as_ntt.[ +- i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- j +- (cast (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative ((secret_as_ntt.[ +- i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] +- <: +- i32) +- <: +- u16) +- <: +- i32) +- <: +- t_Array i32 (sz 256) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- in +- let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize tt_as_ntt +- i +- ({ +- (tt_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (tt_as_ntt.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- j +- (cast (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative ((tt_as_ntt.[ +- i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] +- <: +- i32) +- <: +- u16) +- <: +- i32) +- <: +- t_Array i32 (sz 256) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- in +- secret_as_ntt, tt_as_ntt +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- in +- let a_matrix:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- a_transpose +- in +- let a_matrix:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = v_K +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- a_matrix +- (fun a_matrix i -> +- let a_matrix:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- v_K = +- a_matrix +- in +- let i:usize = i in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = v_K +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- a_matrix +- (fun a_matrix j -> +- let a_matrix:t_Array +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- a_matrix +- in +- let j:usize = j in +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize a_matrix +- i +- (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (a_matrix.[ i ] +- <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- j +- ((a_transpose.[ j ] - <: -- i32) -+ red - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) - in - re) - in -- re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) -+ re, zeta_i <: t_PolynomialRingElement_b (2*b) & usize) - in -- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) = re in -+ lemma_zeta_decr orig_zeta_i zeta_i layer; -+ zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) -+#pop-options - --let invert_ntt_montgomery (v_K: usize) (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+#push-options "--z3rlimit 500" -+let invert_ntt_montgomery v_K re = - let _:Prims.unit = () <: Prims.unit in -+ let b = v v_K * 3328 in -+ assert (v v_K <= 4); -+ assert (b <= 4 * 3328); - let zeta_i:usize = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT /! sz 2 in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 1) -+ assert (v zeta_i == pow2 (8 - 1)); -+ let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) = -+ invert_ntt_at_layer #v_K #b zeta_i re (sz 1) - in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 2) -+ let hoist1 = out in -+ let re = hoist1 in -+ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (4*b)) = -+ invert_ntt_at_layer #v_K zeta_i re (sz 2) +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K).[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- <: +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- <: +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- in +- (secret_as_ntt, tt_as_ntt, a_matrix +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K)), +- public_key_serialized +- <: +- ((t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & +- t_Array u8 v_PUBLIC_KEY_SIZE) +- +-let generate_keypair +- (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: +- usize) +- (key_generation_seed: t_Slice u8) +- = +- let (secret_as_ntt, v__t_as_ntt, v__a_transpose), public_key_serialized:((t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & +- t_Array u8 v_PUBLIC_KEY_SIZE) = +- generate_keypair_unpacked v_K +- v_PUBLIC_KEY_SIZE +- v_RANKED_BYTES_PER_RING_ELEMENT +- v_ETA1 +- v_ETA1_RANDOMNESS_SIZE +- key_generation_seed ++ serialize_public_key #p v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE tt_as_ntt seed_for_A in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 3) -+ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*b)) = -+ invert_ntt_at_layer #v_K zeta_i re (sz 3) + let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = +- serialize_secret_key v_K v_PRIVATE_KEY_SIZE secret_as_ntt ++ serialize_secret_key #p v_K v_PRIVATE_KEY_SIZE secret_as_ntt in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 4) -+ assert (8*b = v v_K * 3328 * pow2 (4 - 1)); -+ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (16*b)) = -+ invert_ntt_at_layer #v_K zeta_i re (sz 4) - in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 5) -+ assert (16*b == v v_K * 3328 * pow2 (5 - 1)); -+ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (32*b)) = -+ invert_ntt_at_layer #v_K zeta_i re (sz 5) - in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 6) -+ assert (32*b = v v_K * 3328 * pow2 (6 - 1)); -+ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*b)) = -+ invert_ntt_at_layer #v_K zeta_i re (sz 6) - in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- invert_ntt_at_layer zeta_i re (sz 7) -+ assert (64*b = v v_K * 3328 * pow2 (7 - 1)); -+ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (128*b)) = -+ invert_ntt_at_layer #v_K zeta_i re (sz 7) - in - let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in - let _:Prims.unit = () <: Prims.unit in - let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ admit(); -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*b) = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = sz 2 -+ Core.Ops.Range.f_end = sz 8 - } - <: - Core.Ops.Range.t_Range usize) -@@ -144,7 +216,7 @@ - Core.Ops.Range.t_Range usize) - re - (fun re i -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (128*b) = re in - let i:usize = i in - { - re with -@@ -163,52 +235,84 @@ - t_Array i32 (sz 256) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*b)) - in -- re -+ re -+#pop-options - --let ntt_at_layer -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer v__initial_coefficient_bound: usize) -- = -- let step:usize = sz 1 <= 0 /\ v zeta_i <= 63} ) -+ (layer:usize{v layer > 0 /\ -+ v layer <= 7 /\ -+ v zeta_i == pow2 (7 - v layer) - 1}) -+ (x:i32_b b) -+ (i:usize{v i < 128/(pow2 (v layer))}) -+ : i32_b 3328 -+let mul_zeta_red2 #b zeta_i layer x i = -+ let zeta_i = zeta_i +! sz 1 +! i in -+ let zeta = v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] in -+ assert (b * 1664 < 65536 * 3328); -+ let red = Libcrux.Kem.Kyber.Arithmetic.montgomery_multiply_sfe_by_fer #(3328+b) #1664 x -+ (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) in -+ red -+#pop-options -+ -+#push-options "--ifuel 0 --z3rlimit 5000" -+let ntt_at_layer #b zeta_i re layer initial_coefficient_bound = -+ let step = sz 1 < -+ let (re,zeta_i) = acc in -+ v zeta_i == v orig_zeta_i + v i /\ -+ (forall k. v k >= 2 * v i * v step ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]) ++ let res = + secret_key_serialized, public_key_serialized + <: + (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) + in -+ let re, zeta_i: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) & usize) = -+ Rust_primitives.Iterators.foldi_range #_ #(t_PolynomialRingElement_b (3328+b) & usize) #inv { - Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = sz 128 >>! layer <: usize -+ Core.Ops.Range.f_end = loop_end - } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- (re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) -+ (cast_poly_b #b #(3328+b) re, zeta_i) - (fun temp_0_ round -> -- let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize) = temp_0_ in -+ let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) & usize) = temp_0_ in - let round:usize = round in - let zeta_i:usize = zeta_i +! sz 1 in -- let offset:usize = (round *! step <: usize) *! sz 2 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ assert(v round * v step < 128); -+ assert(v round * v step + v step <= 128); -+ assert(v round * v step * 2 <= 254); -+ assert(v round * v step * 2 + 2 * v step <= 256); -+ let offset:usize = (round *! step) *! sz 2 in -+ assert (v offset + 2 * v step <= 256); -+ assert (v offset + v step <= 256); -+ [@ inline_let] -+ let inv: t_PolynomialRingElement_b (3328+b) -> int_t usize_inttype -> Type0 = -+ fun (acc:t_PolynomialRingElement_b (3328+b)) (i:usize) -> -+ (forall k. (v k >= v i /\ v k < v offset + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) /\ -+ (forall k. (v k >= v i + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) -+ in -+ assert (forall k. (v k >= v offset /\ v k < v offset + v step) ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]); -+ assert (forall k. (v k >= v offset + v step) ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]); -+ assert (inv re offset); -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+ b) = -+ Rust_primitives.Iterators.foldi_range #usize_inttype #(t_PolynomialRingElement_b (3328+b)) #inv { - Core.Ops.Range.f_start = offset; - Core.Ops.Range.f_end = offset +! step <: usize -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -+ } - re - (fun re j -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = re in - let j:usize = j in -- let t:i32 = -- Libcrux.Kem.Kyber.Arithmetic.montgomery_multiply_fe_by_fer (re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! step <: usize ] -- <: -- i32) -- (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) -- in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ assert (re.f_coefficients.[j] == orig_re.f_coefficients.[j]); -+ assert (re.f_coefficients.[j +! step] == orig_re.f_coefficients.[j +! step]); -+ let re_j:i32_b b = orig_re.f_coefficients.[j] in -+ let re_j_step:i32_b b = orig_re.f_coefficients.[j +! step] in -+ let t:i32_b 3328 = mul_zeta_red2 #b orig_zeta_i layer -+ re_j_step round in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -216,12 +320,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (j +! step <: usize) -- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) -! t <: i32) -+ (sub_i32_b #b #3328 re_j_step t) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -229,64 +333,70 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - j -- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +! t <: i32) -+ (add_i32_b #b #3328 re_j t) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) - in - re) - in -- re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) -+ re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) & usize)) - in - let _:Prims.unit = () <: Prims.unit in -- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = re in -+ assert (v zeta_i = v orig_zeta_i + 128/v step); -+ assert (v zeta_i = v orig_zeta_i + pow2(7 - v layer)); -+ assert (v zeta_i = pow2(8 - v layer) - 1); -+ zeta_i, hax_temp_output -+#pop-options - --let ntt_at_layer_3_ -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer: usize) -- = -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- ntt_at_layer zeta_i re layer (sz 3) -+let ntt_at_layer_3_ #b zeta_i re layer = -+ let tmp0, out = -+ ntt_at_layer zeta_i re layer (sz 7879) - in - let zeta_i:usize = tmp0 in -- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- --let ntt_at_layer_3328_ -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer: usize) -- = -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let hax_temp_output = out in -+ zeta_i, hax_temp_output ++ res + -+let ntt_at_layer_3328_ zeta_i re layer = -+ let tmp0, out = - ntt_at_layer zeta_i re layer (sz 3328) - in - let zeta_i:usize = tmp0 in -- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ let hax_temp_output = out in -+ zeta_i, hax_temp_output +diff -ruN extraction/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti +--- extraction/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-14 15:56:45.380357237 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-14 15:56:45.469355777 +0200 +@@ -1,196 +1,151 @@ + module Libcrux.Kem.Kyber.Ind_cpa +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" + open Core + open FStar.Mul --let ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+#push-options "--ifuel 0 --z3rlimit 1500" -+#restart-solver -+let ntt_binomially_sampled_ring_element re = - let _:Prims.unit = () <: Prims.unit in - let zeta_i:usize = sz 1 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ [@ inline_let] -+ let inv = fun (acc:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207)) (i:usize) -> -+ (v i <= 128) /\ -+ (forall (j:usize). (v j >= v i /\ v j < 128) ==> -+ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207).f_coefficients.[j] 7) /\ -+ (forall (j:usize). (v j >= v i + 128 /\ v j < 256) ==> -+ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207).f_coefficients.[j] 7) -+ in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207 = cast_poly_b re in -+ assert (inv re (sz 0)); -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207 = -+ Rust_primitives.Iterators.foldi_range #_ #(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207) #inv ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = sz 128 - } - <: - Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -- re -+ (cast_poly_b re) - (fun re j -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207 = cast_poly_b re in - let j:usize = j in -- let t:i32 = -- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! sz 128 <: usize ] <: i32) *! -- (-1600l) -+ let t:i32_b (7*1600) = -+ mul_i32_b (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! sz 128 <: usize ]) -+ (-1600l <: i32_b 1600) - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (11207) = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -294,12 +404,10 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (j +! sz 128 <: usize) -- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) -! t <: i32) -+ (sub_i32_b #7 #11200 (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32_b 7) t) - } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (11207) = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -307,84 +415,76 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - j -- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +! t <: i32) -+ (add_i32_b (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ]) t) - } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement - in - re) - in - let _:Prims.unit = () <: Prims.unit in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ assert (v zeta_i = pow2 (7 - 6) - 1); -+ let zeta_i, re = - ntt_at_layer_3_ zeta_i re (sz 6) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3_ zeta_i re (sz 5) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3_ zeta_i re (sz 4) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3_ zeta_i re (sz 3) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3_ zeta_i re (sz 2) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3_ zeta_i re (sz 1) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207) = re in -+ [@ inline_let] -+ let inv = fun (acc:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207))) (i:usize) -> -+ (v i <= 256) /\ -+ (forall (j:usize). (v j < v i) ==> -+ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207)).f_coefficients.[j] 3328) -+ in -+ assert (inv re (sz 0)); -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207) = -+ Rust_primitives.Iterators.foldi_range #_ #(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207)) #inv ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT - } - <: - Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) - re - (fun re i -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207) = re in -+ let rei:i32_b (v v_BARRETT_R) = cast_i32_b #(6*3328+11207) #(v v_BARRETT_R) (re -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ]) in -+ let rei: i32_b (6*3328+11207) = cast_i32_b #3328 #(6*3328+11207) ( -+ Libcrux.Kem.Kyber.Arithmetic.barrett_reduce rei) in - let i:usize = i in -+ let re_coeffs:t_Array (i32_b (6*3328+11207)) (sz 256) = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ i rei in - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- i -- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) -- <: -- i32) -- <: -- t_Array i32 (sz 256) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ = re_coeffs -+ }) - in -- re -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = down_cast_poly_b #(6*3328+11207) #3328 re in -+ re -+#pop-options +-/// Pad the `slice` with `0`s at the end. +-val into_padded_array (v_LEN: usize) (slice: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) ++val into_padded_array (v_LEN: usize) (slice: t_Slice u8) : ++ Pure (t_Array u8 v_LEN) ++ (requires (length slice <=. v_LEN)) ++ (ensures (fun res -> Seq.slice res 0 (Seq.length slice) == slice)) --let ntt_multiply (lhs rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +-/// Sample a vector of ring elements from a centered binomial distribution. +-val sample_ring_element_cbd ++val sample_vector_cbd (#p:Spec.Kyber.params) + (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) + (prf_input: t_Array u8 (sz 33)) + (domain_separator: u8) +- : Prims.Pure +- (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// Sample a vector of ring elements from a centered binomial distribution and +-/// convert them into their NTT representations. +-val sample_vector_cbd_then_ntt ++ : Pure (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (requires v domain_separator <= v v_K /\ v_K <=. sz 4 /\ ++ v_K = p.v_RANK /\ v_ETA2 = p.v_ETA2 /\ ++ v_ETA2_RANDOMNESS_SIZE = Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p) ++ (ensures (fun (prf,ds,x) -> v ds == v domain_separator + v v_K /\ ++ Seq.slice prf 0 32 == Seq.slice prf_input 0 32 /\ ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p x == ++ Spec.Kyber.sample_vector_cbd #p (Seq.slice prf_input 0 32) (sz (v domain_separator)))) + -+#push-options "--z3rlimit 100" -+let ntt_multiply lhs rhs = - let _:Prims.unit = () <: Prims.unit in -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 1 = - Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end -@@ -395,34 +495,31 @@ - Core.Ops.Range.t_Range usize) - <: - Core.Ops.Range.t_Range usize) -- out -+ (cast_poly_b out) - (fun out i -> -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = out in - let i:usize = i in -- let product:(i32 & i32) = -+ assert (v i * 4 + 4 <= 256); -+ let product = - ntt_multiply_binomials ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ sz 4 *! i - <: - usize ] - <: -- i32), -+ i32_b 3328), - (lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 1 - <: - usize ] - <: -- i32) -- <: -- (i32 & i32)) -- ((rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ sz 4 *! i <: usize ] <: i32), -+ i32_b 3328)) -+ ((rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ sz 4 *! i <: usize ] <: i32_b 3328), - (rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 1 - <: - usize ] - <: -- i32) -- <: -- (i32 & i32)) -- (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ] <: i32) -+ i32_b 3328)) -+ (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ] <: i32_b 1664) - in -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = - { - out with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -433,9 +530,9 @@ - product._1 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 - in -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = - { - out with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -446,41 +543,29 @@ - product._2 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 - in -- let product:(i32 & i32) = -+ let product = - ntt_multiply_binomials ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i - <: - usize) +! - sz 2 - <: -- usize ] -- <: -- i32), -+ usize ]), - (lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 3 - <: -- usize ] -- <: -- i32) -- <: -- (i32 & i32)) -+ usize ])) -+ - ((rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 2 - <: -- usize ] -- <: -- i32), -+ usize ]), - (rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 3 - <: -- usize ] -- <: -- i32) -- <: -- (i32 & i32)) -- (Core.Ops.Arith.Neg.neg (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ] <: i32) -- <: -- i32) -+ usize ])) -+ (Core.Ops.Arith.Neg.neg (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ]) <: i32_b 1664) + - in -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = - { - out with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -491,9 +576,9 @@ - product._1 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 - in -- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = - { - out with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -504,65 +589,55 @@ - product._2 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 - in - out) - in - out -+#pop-options - --let ntt_vector_u -- (v_VECTOR_U_COMPRESSION_FACTOR: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- = -+#push-options "--ifuel 0 --z3rlimit 200" -+let ntt_vector_u v_VECTOR_U_COMPRESSION_FACTOR re = - let _:Prims.unit = () <: Prims.unit in - let zeta_i:usize = sz 0 in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 7) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 6) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 5) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 4) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 3) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 2) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+ let zeta_i, re = - ntt_at_layer_3328_ zeta_i re (sz 1) - in -- let zeta_i:usize = tmp0 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -+ [@ inline_let] -+ let inv = fun (acc:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328))) (i:usize) -> -+ (v i <= 256) /\ -+ (forall (j:usize). (v j < v i) ==> -+ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328)).f_coefficients.[j] 3328) -+ in -+ assert (inv re (sz 0)); -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328) = -+ Rust_primitives.Iterators.foldi_range #_ #(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328)) #inv ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT - } - <: - Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) - re - (fun re i -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328) = re in - let i:usize = i in - { - re with -@@ -572,15 +647,10 @@ - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - i - (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) -- <: -- i32) -- <: -- t_Array i32 (sz 256) -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ])) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328)) - in -- re -+ down_cast_poly_b #(8*3328) #3328 re -+#pop-options -diff -ruN extraction/Libcrux.Kem.Kyber.Ntt.fsti extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti ---- extraction/Libcrux.Kem.Kyber.Ntt.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti 2024-05-07 18:38:45 -@@ -2,276 +2,80 @@ - #set-options "--fuel 0 --ifuel 1 --z3rlimit 15" - open Core - open FStar.Mul -+open Libcrux.Kem.Kyber.Arithmetic - --let v_ZETAS_TIMES_MONTGOMERY_R: t_Array i32 (sz 128) = -- let list = -- [ -- (-1044l); (-758l); (-359l); (-1517l); 1493l; 1422l; 287l; 202l; (-171l); 622l; 1577l; 182l; -- 962l; (-1202l); (-1474l); 1468l; 573l; (-1325l); 264l; 383l; (-829l); 1458l; (-1602l); (-130l); -- (-681l); 1017l; 732l; 608l; (-1542l); 411l; (-205l); (-1571l); 1223l; 652l; (-552l); 1015l; -- (-1293l); 1491l; (-282l); (-1544l); 516l; (-8l); (-320l); (-666l); (-1618l); (-1162l); 126l; -- 1469l; (-853l); (-90l); (-271l); 830l; 107l; (-1421l); (-247l); (-951l); (-398l); 961l; -- (-1508l); (-725l); 448l; (-1065l); 677l; (-1275l); (-1103l); 430l; 555l; 843l; (-1251l); 871l; -- 1550l; 105l; 422l; 587l; 177l; (-235l); (-291l); (-460l); 1574l; 1653l; (-246l); 778l; 1159l; -- (-147l); (-777l); 1483l; (-602l); 1119l; (-1590l); 644l; (-872l); 349l; 418l; 329l; (-156l); -- (-75l); 817l; 1097l; 603l; 610l; 1322l; (-1285l); (-1465l); 384l; (-1215l); (-136l); 1218l; -- (-1335l); (-874l); 220l; (-1187l); (-1659l); (-1185l); (-1530l); (-1278l); 794l; (-1510l); -- (-854l); (-870l); 478l; (-108l); (-308l); 996l; 991l; 958l; (-1460l); 1522l; 1628l -- ] -- in -- FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 128); -- Rust_primitives.Hax.array_of_list 128 list -+val v_ZETAS_TIMES_MONTGOMERY_R: x:t_Array (i32_b 1664) (sz 128){v (x.[sz 1] <: i32) == -758} - --/// Compute the product of two Kyber binomials with respect to the --/// modulus `X² - zeta`. --/// This function almost implements Algorithm 11 of the --/// NIST FIPS 203 standard, which is reproduced below: --/// ```plaintext --/// Input: a₀, a₁, b₀, b₁ ∈ ℤq. --/// Input: γ ∈ ℤq. --/// Output: c₀, c₁ ∈ ℤq. --/// c₀ ← a₀·b₀ + a₁·b₁·γ --/// c₁ ← a₀·b₁ + a₁·b₀ --/// return c₀, c₁ --/// ``` --/// We say "almost" because the coefficients output by this function are in --/// the Montgomery domain (unlike in the specification). --/// The NIST FIPS 203 standard can be found at --/// . --val ntt_multiply_binomials: (i32 & i32) -> (i32 & i32) -> zeta: i32 -- -> Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) -+val ntt_multiply_binomials (a:wfFieldElement&wfFieldElement) (b: wfFieldElement&wfFieldElement) (zeta: i32_b 1664) : -+ Pure (wfFieldElement & wfFieldElement) -+ (requires True) -+ (ensures (fun _ -> True)) - --val invert_ntt_at_layer -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer: usize) -- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+val invert_ntt_at_layer (#v_K:usize{v v_K >= 1 /\ v v_K <= 4}) -+ (#b:nat{b <= v v_K * 3328 * 64}) -+ (zeta_i: usize{v zeta_i >= 1 /\ v zeta_i <= 128}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) -+ (layer: usize{v layer > 0 /\ -+ v layer <= 7 /\ -+ v zeta_i == pow2 (8 - v layer) /\ -+ b == v v_K * 3328 * pow2(v layer - 1)}) -+ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) - Prims.l_True -- (fun _ -> Prims.l_True) -+ (fun x -> let (zeta_fin,re) = x in v zeta_fin == pow2 (7 - v layer)) - --/// Use the Gentleman-Sande butterfly to invert, in-place, the NTT representation --/// of a `KyberPolynomialRingElement`. The coefficients of the output --/// ring element are in the Montgomery domain. --val invert_ntt_montgomery (v_K: usize) (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++val sample_vector_cbd_then_ntt (#p:Spec.Kyber.params) + (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) + (prf_input: t_Array u8 (sz 33)) +- (domain_separator: u8) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & u8) - Prims.l_True - (fun _ -> Prims.l_True) -+val invert_ntt_montgomery (v_K: usize{v v_K >= 1 /\ v v_K <= 4}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) -+ : Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) - --/// Represents an intermediate polynomial splitting step in the NTT. All --/// resulting coefficients are in the normal domain since the zetas have been --/// multiplied by MONTGOMERY_R. --val ntt_at_layer -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer v__initial_coefficient_bound: usize) -- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- Prims.l_True -- (fun _ -> Prims.l_True) -+val ntt_at_layer -+ (#b:nat{b <= 31175}) -+ (zeta_i: usize{v zeta_i < 128}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) -+ (layer: usize{v layer > 0 /\ -+ v layer <= 7 /\ -+ v zeta_i == pow2 (7 - v layer) - 1}) -+ (initial_coefficient_bound: usize{b == (7 - v layer) * 3328 + v initial_coefficient_bound}) -+ : Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) -+ (requires True) -+ (ensures fun (zeta_i, result) -> v zeta_i == pow2 (8 - v layer) - 1) - --/// See [`ntt_at_layer`]. --val ntt_at_layer_3_ -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer: usize) -- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+val ntt_at_layer_3_ (#b:nat) -+ (zeta_i: usize{v zeta_i < 128}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) -+ (layer: usize{v layer > 0 /\ -+ v layer <= 6 /\ -+ v zeta_i == pow2 (7 - v layer) - 1 /\ -+ b == (6 - v layer) * 3328 + 11207}) -+ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) - Prims.l_True -- (fun _ -> Prims.l_True) -+ (ensures fun (zeta_i,result) -> v zeta_i == pow2 (8 - v layer) - 1) - --/// See [`ntt_at_layer`]. --val ntt_at_layer_3328_ -- (zeta_i: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- (layer: usize) -- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+val ntt_at_layer_3328_ (#b:nat{b <= 7*3328}) -+ (zeta_i: usize{v zeta_i < 128}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) -+ (layer: usize{v layer > 0 /\ -+ v layer <= 7 /\ -+ v zeta_i == pow2 (7 - v layer) - 1 /\ -+ b == (7 - v layer) * 3328 + 3328}) -+ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) - Prims.l_True -- (fun _ -> Prims.l_True) -+ (ensures fun (zeta_i,result) -> v zeta_i == pow2 (8 - v layer) - 1) - --/// Use the Cooley–Tukey butterfly to compute an in-place NTT representation --/// of a `KyberPolynomialRingElement`. --/// This function operates only on those which were produced by binomial --/// sampling, and thus those which have small coefficients. The small --/// coefficients let us skip the first round of Montgomery reductions. --val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- (requires -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) -- <: -- i32) <=. -- 3l -- <: -- bool) -- <: -- bool)) -- (ensures -- fun result -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ -- i ] -- <: -- i32) -- <: -- i32) <. -- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- bool) -- <: -- bool)) -+val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7) -+ : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires True) -+ (ensures (fun _ -> True)) ++ (domain_separator: u8{v domain_separator <= v v_K /\ v_K <=. sz 4}) ++ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & u8) ++ (requires (v_K == p.v_RANK /\ v_ETA == p.v_ETA1 /\ v_ETA_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p)) ++ (ensures (fun (x,ds) -> v ds == v domain_separator + v v_K /\ ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p x == ++ Spec.Kyber.sample_vector_cbd_then_ntt #p (Seq.slice prf_input 0 32) (sz (v domain_separator)))) --/// Given two `KyberPolynomialRingElement`s in their NTT representations, --/// compute their product. Given two polynomials in the NTT domain `f^` and `ĵ`, --/// the `iᵗʰ` coefficient of the product `k\u{302}` is determined by the calculation: +-/// Call [`compress_then_serialize_ring_element_u`] on each ring element. +-val compress_then_serialize_u ++val compress_then_serialize_u (#p:Spec.Kyber.params) + (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) +- (input: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) +- +-/// This function implements Algorithm 13 of the +-/// NIST FIPS 203 specification; this is the Kyber CPA-PKE encryption algorithm. +-/// Algorithm 13 is reproduced below: -/// ```plaintext --/// ĥ[2·i] + ĥ[2·i + 1]X = (f^[2·i] + f^[2·i + 1]X)·(ĝ[2·i] + ĝ[2·i + 1]X) mod (X² - ζ^(2·BitRev₇(i) + 1)) +-/// Input: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. +-/// Input: message m ∈ 𝔹^{32}. +-/// Input: encryption randomness r ∈ 𝔹^{32}. +-/// Output: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. +-/// N ← 0 +-/// t̂ ← ByteDecode₁₂(ekₚₖₑ[0:384k]) +-/// ρ ← ekₚₖₑ[384k: 384k + 32] +-/// for (i ← 0; i < k; i++) +-/// for(j ← 0; j < k; j++) +-/// Â[i,j] ← SampleNTT(XOF(ρ, i, j)) +-/// end for +-/// end for +-/// for(i ← 0; i < k; i++) +-/// r[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(r,N)) +-/// N ← N + 1 +-/// end for +-/// for(i ← 0; i < k; i++) +-/// e₁[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) +-/// N ← N + 1 +-/// end for +-/// e₂ ← SamplePolyCBD_{η₂}(PRF_{η₂}(r,N)) +-/// r̂ ← NTT(r) +-/// u ← NTT-¹(Âᵀ ◦ r̂) + e₁ +-/// μ ← Decompress₁(ByteDecode₁(m))) +-/// v ← NTT-¹(t̂ᵀ ◦ rˆ) + e₂ + μ +-/// c₁ ← ByteEncode_{dᵤ}(Compress_{dᵤ}(u)) +-/// c₂ ← ByteEncode_{dᵥ}(Compress_{dᵥ}(v)) +-/// return c ← (c₁ ‖ c₂) -/// ``` --/// This function almost implements Algorithm 10 of the --/// NIST FIPS 203 standard, which is reproduced below: +-/// The NIST FIPS 203 standard can be found at +-/// . +-val encrypt_unpacked +- (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: +- usize) +- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (a_transpose: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- (message: t_Array u8 (sz 32)) +- (randomness: t_Slice u8) +- : Prims.Pure (t_Array u8 v_CIPHERTEXT_SIZE) Prims.l_True (fun _ -> Prims.l_True) ++ (input: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ : Pure (t_Array u8 v_OUT_LEN) ++ (requires (v_K == p.v_RANK /\ v_OUT_LEN == Spec.Kyber.v_C1_SIZE p /\ ++ v_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR /\ ++ v_BLOCK_LEN = Spec.Kyber.v_C1_BLOCK_SIZE p)) ++ (ensures (fun res -> ++ res == Spec.Kyber.compress_then_encode_u p ++ (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p input))) + +-/// Call [`deserialize_then_decompress_ring_element_u`] on each ring element +-/// in the `ciphertext`. +-val deserialize_then_decompress_u +- (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) ++val deserialize_then_decompress_u (#p:Spec.Kyber.params) ++ (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR: usize) + (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// This function implements Algorithm 14 of the +-/// NIST FIPS 203 specification; this is the Kyber CPA-PKE decryption algorithm. +-/// Algorithm 14 is reproduced below: -/// ```plaintext --/// Input: Two arrays fˆ ∈ ℤ₂₅₆ and ĝ ∈ ℤ₂₅₆. --/// Output: An array ĥ ∈ ℤq. --/// for(i ← 0; i < 128; i++) --/// (ĥ[2i], ĥ[2i+1]) ← BaseCaseMultiply(fˆ[2i], fˆ[2i+1], ĝ[2i], ĝ[2i+1], ζ^(2·BitRev₇(i) + 1)) --/// end for --/// return ĥ +-/// Input: decryption key dkₚₖₑ ∈ 𝔹^{384k}. +-/// Input: ciphertext c ∈ 𝔹^{32(dᵤk + dᵥ)}. +-/// Output: message m ∈ 𝔹^{32}. +-/// c₁ ← c[0 : 32dᵤk] +-/// c₂ ← c[32dᵤk : 32(dᵤk + dᵥ)] +-/// u ← Decompress_{dᵤ}(ByteDecode_{dᵤ}(c₁)) +-/// v ← Decompress_{dᵥ}(ByteDecode_{dᵥ}(c₂)) +-/// ŝ ← ByteDecode₁₂(dkₚₖₑ) +-/// w ← v - NTT-¹(ŝᵀ ◦ NTT(u)) +-/// m ← ByteEncode₁(Compress₁(w)) +-/// return m -/// ``` --/// We say \"almost\" because the coefficients of the ring element output by --/// this function are in the Montgomery domain. -/// The NIST FIPS 203 standard can be found at -/// . --val ntt_multiply (lhs rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- (requires -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] <: i32) >=. 0l <: bool) && -- ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] <: i32) <. 4096l <: bool -- ) && -- ((Core.Num.impl__i32__abs (rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) -- <: -- i32) <=. -- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- bool)) -- <: -- bool)) -- (ensures -- fun result -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ -- i ] -- <: -- i32) -- <: -- i32) <=. -- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- bool) -- <: -- bool)) -- --/// Use the Cooley–Tukey butterfly to compute an in-place NTT representation --/// of a `KyberPolynomialRingElement`. --/// This function operates on the ring element that partly constitutes --/// the ciphertext. -+val ntt_multiply (lhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -+ (rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -+ : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -+ (requires True) -+ (ensures (fun _ -> True)) -+ - val ntt_vector_u - (v_VECTOR_U_COMPRESSION_FACTOR: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- (requires -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] -- <: -- i32) -- <: -- i32) <=. -- 3328l -- <: -- bool) -- <: -- bool)) -- (ensures -- fun result -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ -- i ] -- <: -- i32) -- <: -- i32) <. -- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS -- <: -- bool) -- <: -- bool)) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -+ : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires True) -+ (ensures fun _ -> True) +-val decrypt_unpacked ++ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (requires v_K == p.v_RANK /\ ++ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ ++ v_VECTOR_U_ENCODED_SIZE == Spec.Kyber.v_C1_SIZE p /\ ++ v_U_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR) ++ (ensures fun res -> ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res == ++ Spec.Kyber.(vector_ntt (decode_then_decompress_u p (Seq.slice ciphertext 0 (v (Spec.Kyber.v_C1_SIZE p)))))) + -diff -ruN extraction/Libcrux.Kem.Kyber.Sampling.fst extraction-edited/Libcrux.Kem.Kyber.Sampling.fst ---- extraction/Libcrux.Kem.Kyber.Sampling.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Sampling.fst 2024-05-07 18:38:45 -@@ -3,22 +3,34 @@ - open Core - open FStar.Mul - -+let rejection_sampling_panic_with_diagnostic () : Prims.unit = -+ admit(); // This should never be reachable -+ Rust_primitives.Hax.never_to_any (Core.Panicking.panic "explicit panic" -+ <: -+ Rust_primitives.Hax.t_Never) ++val deserialize_public_key (#p:Spec.Kyber.params) ++ (v_K: usize) (public_key: t_Array u8 (Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p)) ++ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (requires v_K == p.v_RANK /\ ++ length public_key == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p) ++ (ensures fun res -> ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b res == ++ Spec.Kyber.vector_decode_12 #p public_key) ++ ++val deserialize_secret_key (#p:Spec.Kyber.params) (v_K: usize) (secret_key: t_Slice u8) ++ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (requires v_K == p.v_RANK /\ ++ length secret_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p) ++ (ensures fun res -> ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res == ++ Spec.Kyber.vector_decode_12 #p secret_key) ++ + -+#push-options "--ifuel 0 --z3rlimit 100" - let sample_from_binomial_distribution_2_ (randomness: t_Slice u8) = -- let (sampled: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement):Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let sampled: t_PolynomialRingElement_b 3 = -+ cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact randomness (sz 4) <: Core.Slice.Iter.t_ChunksExact u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++val decrypt (#p:Spec.Kyber.params) + (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: + usize) +- (secret_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ (secret_key: t_Slice u8) + (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) ++ : Pure (t_Array u8 (sz 32)) ++ (requires (v_K == p.v_RANK /\ ++ length secret_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ ++ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ ++ v_VECTOR_U_ENCODED_SIZE == Spec.Kyber.v_C1_SIZE p /\ ++ v_U_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR /\ ++ v_V_COMPRESSION_FACTOR == p.v_VECTOR_V_COMPRESSION_FACTOR)) ++ (ensures (fun res -> ++ res == Spec.Kyber.ind_cpa_decrypt p secret_key ciphertext)) + -+ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> True in -+ let sl : t_Slice u8 = randomness in -+ let chunk_len = sz 4 in -+ assert (v (length sl) == 128); -+ assert (Seq.length sl == 128); -+ assert_norm (128 % 4 == 0); -+ let sampled = -+ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv -+ sl -+ chunk_len - sampled - (fun sampled temp_1_ -> -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in -- let chunk_number, byte_chunk:(usize & t_Slice u8) = temp_1_ in -+ let chunk_number, byte_chunk:(usize & t_Array u8 chunk_len) = temp_1_ in -+ assert(chunk_number <. sz 32); - let (random_bits_as_u32: u32):u32 = - (((cast (byte_chunk.[ sz 0 ] <: u8) <: u32) |. - ((cast (byte_chunk.[ sz 1 ] <: u8) <: u32) <>! 1l <: u32) &. 1431655765ul in -+ logand_lemma (random_bits_as_u32 >>! 1l <: u32) 1431655765ul; -+ assert(odd_bits <=. 1431655765ul); - let coin_toss_outcomes:u32 = even_bits +! odd_bits in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_step_by -- ({ -+ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 in -+ [@ inline_let] -+ let inv : acc_t -> u32 -> Type = fun acc i -> True in -+ Rust_primitives.Iterators.foldi_range_step_by #u32_inttype #(acc_t) #inv ({ - Core.Ops.Range.f_start = 0ul; - Core.Ops.Range.f_end = Core.Num.impl__u32__BITS -- } -- <: -- Core.Ops.Range.t_Range u32) -- (sz 4) -- <: -- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range u32)) -- <: -- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range u32)) -+ } -+ <: -+ Core.Ops.Range.t_Range u32) -+ (sz 4) - sampled - (fun sampled outcome_set -> -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in - let outcome_set:u32 = outcome_set in -+ assert (v outcome_set + 4 <= 32); -+ let out_1 = ((coin_toss_outcomes >>! outcome_set <: u32) &. 3ul <: u32) in - let outcome_1_:i32 = -- cast ((coin_toss_outcomes >>! outcome_set <: u32) &. 3ul <: u32) <: i32 -+ cast out_1 <: i32 - in -+ let out_2 = ((coin_toss_outcomes >>! (outcome_set +! 2ul <: u32) <: u32) &. 3ul <: u32) in - let outcome_2_:i32 = -- cast ((coin_toss_outcomes >>! (outcome_set +! 2ul <: u32) <: u32) &. 3ul <: u32) -- <: -- i32 -+ cast out_2 <: i32 - in -+ logand_lemma (coin_toss_outcomes >>! outcome_set <: u32) 3ul; -+ assert (v out_1 >= 0); -+ assert (v out_1 <= 3); -+ assert (v outcome_1_ == v out_1 @% pow2 32); -+ Math.Lemmas.small_modulo_lemma_1 (v out_1) (pow2 32); -+ assert (v outcome_1_ == v out_1); -+ assert (v outcome_1_ >= 0 /\ v outcome_1_ <= 3); -+ logand_lemma (coin_toss_outcomes >>! (outcome_set +! 2ul <: u32) <: u32) 3ul; -+ assert (v out_2 >= 0); -+ assert (v out_2 <= 3); -+ assert (v outcome_2_ == v out_2 @% pow2 32); -+ Math.Lemmas.small_modulo_lemma_1 (v out_2) (pow2 32); -+ assert (v outcome_2_ == v out_2); -+ assert (v outcome_2_ >= 0 /\ v outcome_2_ <= 3); - let offset:usize = cast (outcome_set >>! 2l <: u32) <: usize in -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ assert (outcome_set <. 32ul); -+ assert (v (outcome_set >>! 2l <: u32) = v outcome_set / 4); -+ assert (v (outcome_set >>! 2l <: u32) < 8); -+ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set >>! 2l <: u32)) (pow2 32); -+ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set >>! 2l <: u32)) (pow2 64); -+ assert (v offset < 8); -+ assert (8 * v chunk_number + 8 <= 256); -+ assert (8 * v chunk_number + v offset < 256); -+ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 = - { - sampled with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -68,29 +104,36 @@ - (outcome_1_ -! outcome_2_ <: i32) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 - in - sampled)) -- in -- let _:Prims.unit = () <: Prims.unit in -- sampled -+ in -+ let _:Prims.unit = () <: Prims.unit in -+ admit(); // P-F -+ sampled -+#pop-options - -+#push-options "--ifuel 0 --z3rlimit 200" - let sample_from_binomial_distribution_3_ (randomness: t_Slice u8) = -- let (sampled: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement):Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let sampled:t_PolynomialRingElement_b 7 = -+ (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) - in -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact randomness (sz 3) <: Core.Slice.Iter.t_ChunksExact u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) (i:usize) -> True in -+ let sl : t_Slice u8 = randomness in -+ let chunk_len = sz 3 in -+ assert (v (length sl) == 192); -+ assert (Seq.length sl == 192); -+ assert_norm (192 % 3 == 0); -+ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = -+ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv -+ sl -+ chunk_len - sampled - (fun sampled temp_1_ -> -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in -- let chunk_number, byte_chunk:(usize & t_Slice u8) = temp_1_ in -+ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = sampled in -+ let chunk_number, byte_chunk:(usize & t_Array u8 chunk_len) = temp_1_ in - let (random_bits_as_u24: u32):u32 = - ((cast (byte_chunk.[ sz 0 ] <: u8) <: u32) |. - ((cast (byte_chunk.[ sz 1 ] <: u8) <: u32) <>! 1l <: u32) &. 2396745ul in -+ logand_lemma (random_bits_as_u24 >>! 1l <: u32) 2396745ul; -+ assert (second_bits <=. 2396745ul); - let third_bits:u32 = (random_bits_as_u24 >>! 2l <: u32) &. 2396745ul in -+ logand_lemma (random_bits_as_u24 >>! 2l <: u32) 2396745ul; -+ assert (third_bits <=. 2396745ul); - let coin_toss_outcomes:u32 = (first_bits +! second_bits <: u32) +! third_bits in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_step_by -- ({ Core.Ops.Range.f_start = 0l; Core.Ops.Range.f_end = 24l } -- <: -- Core.Ops.Range.t_Range i32) -- (sz 6) -- <: -- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range i32)) -- <: -- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range i32)) -+ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 in -+ [@ inline_let] -+ let inv : acc_t -> i32 -> Type = fun acc i -> True in -+ Rust_primitives.Iterators.foldi_range_step_by #i32_inttype #(acc_t) #inv ({ -+ Core.Ops.Range.f_start = 0l; -+ Core.Ops.Range.f_end = 24l -+ } -+ <: -+ Core.Ops.Range.t_Range i32) -+ (sz 6) - sampled - (fun sampled outcome_set -> -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in -+ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = sampled in - let outcome_set:i32 = outcome_set in - let outcome_1_:i32 = - cast ((coin_toss_outcomes >>! outcome_set <: u32) &. 7ul <: u32) <: i32 -@@ -123,8 +173,22 @@ - <: - i32 - in -+ logand_lemma (coin_toss_outcomes >>! outcome_set <: u32) 7ul; -+ Math.Lemmas.small_modulo_lemma_1 (v ((coin_toss_outcomes >>! outcome_set <: u32) &. 7ul <: u32)) (pow2 32); -+ assert (v outcome_1_ >= 0 /\ v outcome_1_ <= 7); -+ logand_lemma (coin_toss_outcomes >>! (outcome_set +! 3l <: i32) <: u32) 7ul; -+ Math.Lemmas.small_modulo_lemma_1 (v ((coin_toss_outcomes >>! (outcome_set +! 3l <: i32) <: u32) &. 7ul <: u32)) (pow2 32); -+ assert (v outcome_2_ >= 0 /\ v outcome_2_ <= 7); - let offset:usize = cast (outcome_set /! 6l <: i32) <: usize in -- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ assert (outcome_set <. 24l); -+ assert (v (outcome_set /! 6l <: i32) = v outcome_set / 6); -+ assert (v (outcome_set /! 6l <: i32) < 4); -+ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set /! 6l <: i32)) (pow2 32); -+ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set /! 6l <: i32)) (pow2 64); -+ assert (v offset < 4); -+ assert (4 * v chunk_number + 4 <= 256); -+ assert (4 * v chunk_number + v offset < 256); -+ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = - { - sampled with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -135,15 +199,18 @@ - (outcome_1_ -! outcome_2_ <: i32) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 - in - sampled)) - in - let _:Prims.unit = () <: Prims.unit in -+ admit(); - sampled -+#pop-options - let sample_from_binomial_distribution (v_ETA: usize) (randomness: t_Slice u8) = - let _:Prims.unit = () <: Prims.unit in -+ Rust_primitives.Integers.mk_int_equiv_lemma #u32_inttype (v v_ETA); - match cast (v_ETA <: usize) <: u32 with - | 2ul -> sample_from_binomial_distribution_2_ randomness - | 3ul -> sample_from_binomial_distribution_3_ randomness -@@ -153,226 +220,131 @@ - <: - Rust_primitives.Hax.t_Never) +-val encrypt ++val encrypt (#p:Spec.Kyber.params) + (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) + (public_key: t_Slice u8) + (message: t_Array u8 (sz 32)) +- (randomness: t_Slice u8) +- : Prims.Pure (t_Array u8 v_CIPHERTEXT_SIZE) Prims.l_True (fun _ -> Prims.l_True) +- +-/// Call [`deserialize_to_uncompressed_ring_element`] for each ring element. +-val deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-val decrypt +- (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: +- usize) +- (secret_key: t_Slice u8) +- (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +- +-/// Call [`serialize_uncompressed_ring_element`] for each ring element. +-val serialize_secret_key ++ (randomness: t_Slice u8{length randomness <. sz 33}) ++ : Pure (t_Array u8 v_CIPHERTEXT_SIZE) ++ (requires (v_K == p.v_RANK /\ ++ v_ETA1 = p.v_ETA1 /\ ++ v_ETA1_RANDOMNESS_SIZE = Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ ++ v_ETA2 = p.v_ETA2 /\ ++ v_BLOCK_LEN == Spec.Kyber.v_C1_BLOCK_SIZE p /\ ++ v_ETA2_RANDOMNESS_SIZE = Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ ++ v_U_COMPRESSION_FACTOR == p.v_VECTOR_U_COMPRESSION_FACTOR /\ ++ v_V_COMPRESSION_FACTOR == p.v_VECTOR_V_COMPRESSION_FACTOR /\ ++ length public_key == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ length randomness == Spec.Kyber.v_SHARED_SECRET_SIZE /\ ++ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ ++ v_T_AS_NTT_ENCODED_SIZE == Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p /\ ++ v_C1_LEN == Spec.Kyber.v_C1_SIZE p /\ ++ v_C2_LEN == Spec.Kyber.v_C2_SIZE p)) ++ (ensures (fun ct -> ct == Spec.Kyber.ind_cpa_encrypt p public_key message randomness)) ++ ++val serialize_secret_key (#p:Spec.Kyber.params) + (v_K v_OUT_LEN: usize) +- (key: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) +- +-/// Concatenate `t` and `ρ` into the public key. +-val serialize_public_key ++ (key: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ : Pure (t_Array u8 v_OUT_LEN) ++ (requires (v_K == p.v_RANK /\ v_OUT_LEN == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) ++ (ensures (fun res -> ++ res == Spec.Kyber.vector_encode_12 #p ++ (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p key))) ++ ++val serialize_public_key (#p:Spec.Kyber.params) + (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) +- (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) + (seed_for_a: t_Slice u8) +- : Prims.Pure (t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) +- +-/// This function implements most of Algorithm 12 of the +-/// NIST FIPS 203 specification; this is the Kyber CPA-PKE key generation algorithm. +-/// We say "most of" since Algorithm 12 samples the required randomness within +-/// the function itself, whereas this implementation expects it to be provided +-/// through the `key_generation_seed` parameter. +-/// Algorithm 12 is reproduced below: +-/// ```plaintext +-/// Output: encryption key ekₚₖₑ ∈ 𝔹^{384k+32}. +-/// Output: decryption key dkₚₖₑ ∈ 𝔹^{384k}. +-/// d ←$ B +-/// (ρ,σ) ← G(d) +-/// N ← 0 +-/// for (i ← 0; i < k; i++) +-/// for(j ← 0; j < k; j++) +-/// Â[i,j] ← SampleNTT(XOF(ρ, i, j)) +-/// end for +-/// end for +-/// for(i ← 0; i < k; i++) +-/// s[i] ← SamplePolyCBD_{η₁}(PRF_{η₁}(σ,N)) +-/// N ← N + 1 +-/// end for +-/// for(i ← 0; i < k; i++) +-/// e[i] ← SamplePolyCBD_{η₂}(PRF_{η₂}(σ,N)) +-/// N ← N + 1 +-/// end for +-/// ŝ ← NTT(s) +-/// ê ← NTT(e) +-/// t̂ ← Â◦ŝ + ê +-/// ekₚₖₑ ← ByteEncode₁₂(t̂) ‖ ρ +-/// dkₚₖₑ ← ByteEncode₁₂(ŝ) +-/// ``` +-/// The NIST FIPS 203 standard can be found at +-/// . +-val generate_keypair_unpacked +- (v_K v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: usize) +- (key_generation_seed: t_Slice u8) +- : Prims.Pure +- ((t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & +- t_Array u8 v_PUBLIC_KEY_SIZE) Prims.l_True (fun _ -> Prims.l_True) ++ : Pure (t_Array u8 v_PUBLIC_KEY_SIZE) ++ (requires (v_K == p.v_RANK /\ ++ v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p /\ ++ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ length seed_for_a == sz 32)) ++ (ensures (fun res -> res == Seq.append (Spec.Kyber.vector_encode_12 ++ (Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p tt_as_ntt)) ++ seed_for_a)) --let sample_from_uniform_distribution_next -- (v_K v_N: usize) -- (randomness: t_Array (t_Array u8 v_N) v_K) -- (sampled_coefficients: t_Array usize v_K) -- (out: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- = -- let done:bool = true in -- let done, out, sampled_coefficients:(bool & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = v_K -- } -- <: -- Core.Ops.Range.t_Range usize) -- <: -- Core.Ops.Range.t_Range usize) -+#push-options "--z3rlimit 50" -+let sample_from_uniform_distribution (randomness: t_Array u8 (sz 840)) = -+ let (sampled_coefficients: usize):usize = sz 0 in -+ let (out: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement):Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement -+ = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ in -+ let done:bool = false in -+ let acc_t = (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) in -+ [@ inline_let] -+ let inv = fun (acc:acc_t) -> True in -+ let sl : t_Slice u8 = randomness in -+ let chunk_len = sz 3 in -+ let done, out, sampled_coefficients:(bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & -+ usize) = -+ Rust_primitives.Iterators.fold_chunks_exact #u8 #acc_t #inv -+ sl -+ chunk_len - (done, out, sampled_coefficients - <: -- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array usize v_K -- )) -- (fun temp_0_ i -> -+ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize)) -+ (fun temp_0_ bytes -> - let done, out, sampled_coefficients:(bool & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) = -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & -+ usize) = - temp_0_ - in -- let i:usize = i in -- let out, sampled_coefficients:(t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Slice.impl__chunks -- (Rust_primitives.unsize (randomness.[ i ] <: t_Array u8 v_N) <: t_Slice u8) -- (sz 3) -- <: -- Core.Slice.Iter.t_Chunks u8) -+ let bytes:t_Array u8 chunk_len = bytes in -+ if ~.done <: bool -+ then -+ let b1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -+ let b2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -+ let b3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -+ assert(v b1 >= 0 /\ v b1 < pow2 8); -+ assert(v b2 >= 0 /\ v b2 < pow2 8); -+ assert(v b3 >= 0 /\ v b3 < pow2 8); -+ let d1:i32 = ((b2 &. 15l <: i32) <= v b1); -+ assert (v d1 >= 0); -+ let d2:i32 = (b3 <>! 4l <: i32) in -+ logor_lemma (b3 <>! 4l <: i32); -+ assert (v d2 >= v b3 * pow2 4); -+ assert (v d2 >= 0); -+ let out, sampled_coefficients:(Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & -+ usize) = -+ if -+ d1 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && -+ sampled_coefficients <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -+ then -+ let out:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ { -+ out with -+ Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ sampled_coefficients -+ d1 -+ } -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement -+ in -+ out, sampled_coefficients +! sz 1 - <: -- Core.Slice.Iter.t_Chunks u8) -- (out, sampled_coefficients -+ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) -+ else -+ out, sampled_coefficients - <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K)) -- (fun temp_0_ bytes -> -- let out, sampled_coefficients:(t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) = -- temp_0_ -- in -- let bytes:t_Slice u8 = bytes in -- let b1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -- let b2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -- let b3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -- let d1:i32 = ((b2 &. 15l <: i32) <>! 4l <: i32) in -- let out, sampled_coefficients:(t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) = -- if -- d1 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && -- (sampled_coefficients.[ i ] <: usize) <. -- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- then -- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -- i -- ({ -- (out.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (out.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- (sampled_coefficients.[ i ] <: usize) -- d1 -- <: -- t_Array i32 (sz 256) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- in -- out, -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize sampled_coefficients -- i -- ((sampled_coefficients.[ i ] <: usize) +! sz 1 <: usize) -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) -- else -- out, sampled_coefficients -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) -- in -- if -- d2 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && -- (sampled_coefficients.[ i ] <: usize) <. -- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- then -- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -- i -- ({ -- (out.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (out.[ i ] -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- (sampled_coefficients.[ i ] <: usize) -- d2 -- <: -- t_Array i32 (sz 256) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- in -- let sampled_coefficients:t_Array usize v_K = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize sampled_coefficients -- i -- ((sampled_coefficients.[ i ] <: usize) +! sz 1 <: usize) -- in -- out, sampled_coefficients -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) -- else -- out, sampled_coefficients -- <: -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K)) -- in -- if -- (sampled_coefficients.[ i ] <: usize) <. -- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -- then -- false, out, sampled_coefficients -- <: -- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K) -+ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) -+ in -+ let out, sampled_coefficients:(Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & -+ usize) = -+ if -+ d2 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && -+ sampled_coefficients <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -+ then -+ let out:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ { -+ out with -+ Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ = -+ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out -+ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -+ sampled_coefficients -+ d2 -+ } -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement -+ in -+ let sampled_coefficients:usize = sampled_coefficients +! sz 1 in -+ out, sampled_coefficients -+ <: -+ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) -+ else -+ out, sampled_coefficients -+ <: -+ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) -+ in -+ if sampled_coefficients =. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT -+ then -+ let done:bool = true in -+ done, out, sampled_coefficients -+ <: -+ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) -+ else -+ done, out, sampled_coefficients -+ <: -+ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) - else - done, out, sampled_coefficients - <: -- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K)) -+ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize)) - in -- let hax_temp_output:bool = done in -- sampled_coefficients, out, hax_temp_output -- <: -- (t_Array usize v_K & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & bool) -- --let sample_from_xof (v_K: usize) (seeds: t_Array (t_Array u8 (sz 34)) v_K) = -- let (sampled_coefficients: t_Array usize v_K):t_Array usize v_K = -- Rust_primitives.Hax.repeat (sz 0) v_K -+ let _:Prims.unit = -+ if ~.done -+ then -+ let _:Prims.unit = rejection_sampling_panic_with_diagnostic () in -+ () - in -- let (out: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K):t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -- in -- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = -- Libcrux.Kem.Kyber.Hash_functions.absorb v_K seeds -- in -- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & -- t_Array (t_Array u8 (sz 504)) v_K) = -- Libcrux.Kem.Kyber.Hash_functions.squeeze_three_blocks v_K xof_state -- in -- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in -- let randomness:t_Array (t_Array u8 (sz 504)) v_K = out1 in -- let tmp0, tmp1, out1:(t_Array usize v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- bool) = -- sample_from_uniform_distribution_next v_K (sz 504) randomness sampled_coefficients out -- in -- let sampled_coefficients:t_Array usize v_K = tmp0 in -- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = tmp1 in -- let done:bool = out1 in -- let done, out, sampled_coefficients, xof_state:(bool & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K & -- Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = -- Rust_primitives.f_while_loop (fun temp_0_ -> -- let done, out, sampled_coefficients, xof_state:(bool & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K & -- Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = -- temp_0_ -- in -- ~.done <: bool) -- (done, out, sampled_coefficients, xof_state -- <: -- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array usize v_K & -- Libcrux.Digest.Incremental_x4.t_Shake128StateX4)) -- (fun temp_0_ -> -- let done, out, sampled_coefficients, xof_state:(bool & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K & -- Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = -- temp_0_ -- in -- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & -- t_Array (t_Array u8 (sz 168)) v_K) = -- Libcrux.Kem.Kyber.Hash_functions.squeeze_block v_K xof_state -- in -- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in -- let randomness:t_Array (t_Array u8 (sz 168)) v_K = out1 in -- let tmp0, tmp1, out1:(t_Array usize v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- bool) = -- sample_from_uniform_distribution_next v_K (sz 168) randomness sampled_coefficients out -- in -- let sampled_coefficients:t_Array usize v_K = tmp0 in -- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = tmp1 in -- let done:bool = out1 in -- done, out, sampled_coefficients, xof_state -- <: -- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array usize v_K & -- Libcrux.Digest.Incremental_x4.t_Shake128StateX4)) -- in -- let _:Prims.unit = Libcrux.Kem.Kyber.Hash_functions.free_state xof_state in -- out -+ let _:Prims.unit = () <: Prims.unit in -+ out -+#pop-options -diff -ruN extraction/Libcrux.Kem.Kyber.Sampling.fsti extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti ---- extraction/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-07 18:38:45 -@@ -3,155 +3,37 @@ - open Core - open FStar.Mul +-val generate_keypair ++val generate_keypair (#p:Spec.Kyber.params) + (v_K v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_RANKED_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (key_generation_seed: t_Slice u8) +- : Prims.Pure (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Pure (t_Array u8 v_PRIVATE_KEY_SIZE & t_Array u8 v_PUBLIC_KEY_SIZE) ++ (requires (v_K == p.v_RANK /\ ++ v_ETA1 == p.v_ETA1 /\ ++ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ ++ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ ++ v_PRIVATE_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ ++ v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p /\ ++ length key_generation_seed == Spec.Kyber.v_CPA_PKE_KEY_GENERATION_SEED_SIZE)) ++ (ensures (fun (sk,pk) -> (sk,pk) == Spec.Kyber.ind_cpa_generate_keypair p key_generation_seed)) ++ ++ +diff -ruN extraction/Libcrux.Kem.Kyber.Kyber1024.fst extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst +--- extraction/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-14 15:56:45.386357139 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-14 15:56:45.457355974 +0200 +@@ -7,19 +7,19 @@ + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 3168)) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) + = +- Libcrux.Kem.Kyber.decapsulate (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) (sz 1408) ++ Libcrux.Kem.Kyber.decapsulate #Spec.Kyber.kyber1024_params (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) (sz 1408) + (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1600) secret_key ciphertext --/// Given a series of uniformly random bytes in `randomness`, for some number `eta`, --/// the `sample_from_binomial_distribution_{eta}` functions sample --/// a ring element from a binomial distribution centered at 0 that uses two sets --/// of `eta` coin flips. If, for example, --/// `eta = ETA`, each ring coefficient is a value `v` such --/// such that `v ∈ {-ETA, -ETA + 1, ..., 0, ..., ETA + 1, ETA}` and: --/// ```plaintext --/// - If v < 0, Pr[v] = Pr[-v] --/// - If v >= 0, Pr[v] = BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2 ^ (2 * ETA) --/// ``` --/// The values `v < 0` are mapped to the appropriate `KyberFieldElement`. --/// The expected value is: --/// ```plaintext --/// E[X] = (-ETA)Pr[-ETA] + (-(ETA - 1))Pr[-(ETA - 1)] + ... + (ETA - 1)Pr[ETA - 1] + (ETA)Pr[ETA] --/// = 0 since Pr[-v] = Pr[v] when v < 0. --/// ``` --/// And the variance is: --/// ```plaintext --/// Var(X) = E[(X - E[X])^2] --/// = E[X^2] --/// = sum_(v=-ETA to ETA)v^2 * (BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2^(2 * ETA)) --/// = ETA / 2 --/// ``` --/// This function implements Algorithm 7 of the NIST FIPS 203 standard, which is --/// reproduced below: --/// ```plaintext --/// Input: byte array B ∈ 𝔹^{64η}. --/// Output: array f ∈ ℤ₂₅₆. --/// b ← BytesToBits(B) --/// for (i ← 0; i < 256; i++) --/// x ← ∑(j=0 to η - 1) b[2iη + j] --/// y ← ∑(j=0 to η - 1) b[2iη + η + j] --/// f[i] ← x−y mod q --/// end for --/// return f --/// ``` --/// The NIST FIPS 203 standard can be found at --/// . -+open Libcrux.Kem.Kyber.Arithmetic -+ - val sample_from_binomial_distribution_2_ (randomness: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ : Prims.Pure (t_PolynomialRingElement_b 3) - (requires (Core.Slice.impl__len randomness <: usize) =. (sz 2 *! sz 64 <: usize)) - (ensures - fun result -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ -- i ] -- <: -- i32) -- <: -- i32) <=. -- 2l -- <: -- bool) -- <: -- bool)) -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b result == -+ Spec.Kyber.sample_poly_binomial (sz 2) randomness) + let encapsulate + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) + = +- Libcrux.Kem.Kyber.encapsulate (sz 4) (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) ++ Libcrux.Kem.Kyber.encapsulate #Spec.Kyber.kyber1024_params (sz 4) (sz 1568) (sz 1568) (sz 1536) (sz 1408) (sz 160) (sz 11) + (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness - val sample_from_binomial_distribution_3_ (randomness: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ : Prims.Pure (t_PolynomialRingElement_b 7) - (requires (Core.Slice.impl__len randomness <: usize) =. (sz 3 *! sz 64 <: usize)) - (ensures - fun result -> -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in -- Hax_lib.v_forall (fun i -> -- let i:usize = i in -- Hax_lib.implies (i <. -- (Core.Slice.impl__len (Rust_primitives.unsize result -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- <: -- usize) -- <: -- bool) -- (fun temp_0_ -> -- let _:Prims.unit = temp_0_ in -- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ -- i ] -- <: -- i32) -- <: -- i32) <=. -- 3l -- <: -- bool) -- <: -- bool)) -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b result == -+ Spec.Kyber.sample_poly_binomial (sz 3) randomness) + let validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) = + if +- Libcrux.Kem.Kyber.validate_public_key (sz 4) ++ Libcrux.Kem.Kyber.validate_public_key #Spec.Kyber.kyber1024_params (sz 4) + (sz 1536) + (sz 1568) + public_key.Libcrux.Kem.Kyber.Types.f_value +@@ -32,26 +32,8 @@ + <: + Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) --val sample_from_binomial_distribution (v_ETA: usize) (randomness: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+val sample_from_binomial_distribution (#p:Spec.Kyber.params) -+ (v_ETA: usize) (randomness: t_Slice u8) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1)) -+ (requires (v_ETA = p.v_ETA1 \/ v_ETA = p.v_ETA2) /\ -+ (Core.Slice.impl__len randomness <: usize) =. (v_ETA *! sz 64 <: usize)) -+ (ensures -+ fun result -> -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b result == -+ Spec.Kyber.sample_poly_binomial v_ETA randomness) +-let decapsulate_unpacked +- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 4)) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) +- = +- Libcrux.Kem.Kyber.decapsulate_unpacked (sz 4) (sz 3168) (sz 1536) (sz 1568) (sz 1568) (sz 1536) +- (sz 1408) (sz 160) (sz 11) (sz 5) (sz 352) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1600) state +- ciphertext +- + let generate_key_pair (randomness: t_Array u8 (sz 64)) = +- Libcrux.Kem.Kyber.generate_keypair (sz 4) +- (sz 1536) +- (sz 3168) +- (sz 1568) +- (sz 1536) +- (sz 2) +- (sz 128) +- randomness +- +-let generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) = +- Libcrux.Kem.Kyber.generate_keypair_unpacked (sz 4) ++ Libcrux.Kem.Kyber.generate_keypair #Spec.Kyber.kyber1024_params (sz 4) + (sz 1536) + (sz 3168) + (sz 1568) +diff -ruN extraction/Libcrux.Kem.Kyber.Kyber1024.fsti extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti +--- extraction/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-14 15:56:45.397356958 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-14 15:56:45.437356302 +0200 +@@ -71,13 +71,11 @@ + unfold + let t_MlKem1024PublicKey = Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568) --/// If `bytes` contains a set of uniformly random bytes, this function --/// uniformly samples a ring element `â` that is treated as being the NTT representation --/// of the corresponding polynomial `a`. --/// Since rejection sampling is used, it is possible the supplied bytes are --/// not enough to sample the element, in which case an `Err` is returned and the --/// caller must try again with a fresh set of bytes. --/// This function partially implements Algorithm 6 of the NIST FIPS 203 standard, --/// We say "partially" because this implementation only accepts a finite set of --/// bytes as input and returns an error if the set is not enough; Algorithm 6 of --/// the FIPS 203 standard on the other hand samples from an infinite stream of bytes --/// until the ring element is filled. Algorithm 6 is reproduced below: --/// ```plaintext --/// Input: byte stream B ∈ 𝔹*. --/// Output: array â ∈ ℤ₂₅₆. --/// i ← 0 --/// j ← 0 --/// while j < 256 do --/// d₁ ← B[i] + 256·(B[i+1] mod 16) --/// d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] --/// if d₁ < q then --/// â[j] ← d₁ --/// j ← j + 1 --/// end if --/// if d₂ < q and j < 256 then --/// â[j] ← d₂ --/// j ← j + 1 --/// end if --/// i ← i + 3 --/// end while --/// return â --/// ``` --/// The NIST FIPS 203 standard can be found at --/// . --val sample_from_uniform_distribution_next -- (v_K v_N: usize) -- (randomness: t_Array (t_Array u8 v_N) v_K) -- (sampled_coefficients: t_Array usize v_K) -- (out: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +-/// Decapsulate ML-KEM 1024 + val decapsulate + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 3168)) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +-/// Encapsulate ML-KEM 1024 + val encapsulate + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) + (randomness: t_Array u8 (sz 32)) +@@ -85,29 +83,12 @@ + Prims.l_True + (fun _ -> Prims.l_True) + +-/// Validate a public key. +-/// Returns `Some(public_key)` if valid, and `None` otherwise. + val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) + : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568))) + Prims.l_True + (fun _ -> Prims.l_True) + +-unfold +-let t_MlKem1024State = Libcrux.Kem.Kyber.t_MlKemState (sz 4) +- +-val decapsulate_unpacked +- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 4)) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1568)) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +- +-/// Generate ML-KEM 1024 Key Pair + val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair (sz 3168) (sz 1568)) + Prims.l_True + (fun _ -> Prims.l_True) +- +-val generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) - : Prims.Pure -- (t_Array usize v_K & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & bool) +- (Libcrux.Kem.Kyber.t_MlKemState (sz 4) & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1568)) - Prims.l_True - (fun _ -> Prims.l_True) +diff -ruN extraction/Libcrux.Kem.Kyber.Kyber512.fst extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst +--- extraction/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-14 15:56:45.415356663 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-14 15:56:45.422356548 +0200 +@@ -7,19 +7,19 @@ + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 1632)) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) + = +- Libcrux.Kem.Kyber.decapsulate (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) (sz 640) ++ Libcrux.Kem.Kyber.decapsulate #Spec.Kyber.kyber512_params (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) (sz 640) + (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) secret_key ciphertext + + let encapsulate + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) + = +- Libcrux.Kem.Kyber.encapsulate (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) ++ Libcrux.Kem.Kyber.encapsulate #Spec.Kyber.kyber512_params (sz 2) (sz 768) (sz 800) (sz 768) (sz 640) (sz 128) (sz 10) (sz 4) + (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) public_key randomness + + let validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) = + if +- Libcrux.Kem.Kyber.validate_public_key (sz 2) ++ Libcrux.Kem.Kyber.validate_public_key #Spec.Kyber.kyber512_params (sz 2) + (sz 768) + (sz 800) + public_key.Libcrux.Kem.Kyber.Types.f_value +@@ -32,26 +32,8 @@ + <: + Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) + +-let decapsulate_unpacked +- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 2)) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) +- = +- Libcrux.Kem.Kyber.decapsulate_unpacked (sz 2) (sz 1632) (sz 768) (sz 800) (sz 768) (sz 768) +- (sz 640) (sz 128) (sz 10) (sz 4) (sz 320) (sz 3) (sz 192) (sz 2) (sz 128) (sz 800) state +- ciphertext - --val sample_from_xof (v_K: usize) (seeds: t_Array (t_Array u8 (sz 34)) v_K) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + let generate_key_pair (randomness: t_Array u8 (sz 64)) = +- Libcrux.Kem.Kyber.generate_keypair (sz 2) +- (sz 768) +- (sz 1632) +- (sz 800) +- (sz 768) +- (sz 3) +- (sz 192) +- randomness +- +-let generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) = +- Libcrux.Kem.Kyber.generate_keypair_unpacked (sz 2) ++ Libcrux.Kem.Kyber.generate_keypair #Spec.Kyber.kyber512_params (sz 2) + (sz 768) + (sz 1632) + (sz 800) +diff -ruN extraction/Libcrux.Kem.Kyber.Kyber512.fsti extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti +--- extraction/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-14 15:56:45.389357089 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-14 15:56:45.456355990 +0200 +@@ -71,13 +71,11 @@ + unfold + let t_MlKem512PublicKey = Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800) + +-/// Decapsulate ML-KEM 512 + val decapsulate + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 1632)) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +-/// Encapsulate ML-KEM 512 + val encapsulate + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) + (randomness: t_Array u8 (sz 32)) +@@ -85,29 +83,12 @@ + Prims.l_True + (fun _ -> Prims.l_True) + +-/// Validate a public key. +-/// Returns `Some(public_key)` if valid, and `None` otherwise. + val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) + : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800))) + Prims.l_True + (fun _ -> Prims.l_True) + +-unfold +-let t_MlKem512State = Libcrux.Kem.Kyber.t_MlKemState (sz 2) +- +-val decapsulate_unpacked +- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 2)) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 768)) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +- +-/// Generate ML-KEM 512 Key Pair + val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair (sz 1632) (sz 800)) + Prims.l_True + (fun _ -> Prims.l_True) +- +-val generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) +- : Prims.Pure +- (Libcrux.Kem.Kyber.t_MlKemState (sz 2) & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 800)) - Prims.l_True - (fun _ -> Prims.l_True) -+val sample_from_uniform_distribution (randomness: t_Array u8 (sz 840)) -+ : Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement -+ (requires True) -+ (ensures fun _ -> True) -+// (ensures fun result -> (forall i. v (result.f_coefficients.[i]) >= 0)) -+ -diff -ruN extraction/Libcrux.Kem.Kyber.Serialize.fst extraction-edited/Libcrux.Kem.Kyber.Serialize.fst ---- extraction/Libcrux.Kem.Kyber.Serialize.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Serialize.fst 2024-05-07 18:38:45 -@@ -1,8 +1,15 @@ - module Libcrux.Kem.Kyber.Serialize --#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+#set-options "--fuel 0 --ifuel 0 --z3rlimit 50 --retry 3" - open Core - open FStar.Mul - -+open Libcrux.Kem.Kyber.Arithmetic -+ -+open MkSeq -+open BitVecEq -+ -+#push-options "--z3rlimit 480 --split_queries always" -+[@@"opaque_to_smt"] - let compress_coefficients_10_ (coefficient1 coefficient2 coefficient3 coefficient4: i32) = - let coef1:u8 = cast (coefficient1 &. 255l <: i32) <: u8 in - let coef2:u8 = -@@ -18,12 +25,14 @@ - (cast ((coefficient3 >>! 4l <: i32) &. 63l <: i32) <: u8) - in - let coef5:u8 = cast ((coefficient4 >>! 2l <: i32) &. 255l <: i32) <: u8 in -+ bit_vec_equal_intro_principle (); - coef1, coef2, coef3, coef4, coef5 <: (u8 & u8 & u8 & u8 & u8) -+#pop-options +diff -ruN extraction/Libcrux.Kem.Kyber.Kyber768.fst extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst +--- extraction/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-14 15:56:45.412356712 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-14 15:56:45.424356515 +0200 +@@ -7,19 +7,19 @@ + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 2400)) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) + = +- Libcrux.Kem.Kyber.decapsulate (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) (sz 960) ++ Libcrux.Kem.Kyber.decapsulate #Spec.Kyber.kyber768_params (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) (sz 960) + (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1120) secret_key ciphertext -+#push-options "--ifuel 1 --z3rlimit 600 --split_queries always" -+[@@"opaque_to_smt"] - let compress_coefficients_11_ -- (coefficient1 coefficient2 coefficient3 coefficient4 coefficient5 coefficient6 coefficient7 coefficient8: -- i32) -- = -+ coefficient1 coefficient2 coefficient3 coefficient4 coefficient5 coefficient6 coefficient7 coefficient8 = - let coef1:u8 = cast (coefficient1 <: i32) <: u8 in - let coef2:u8 = - ((cast (coefficient2 &. 31l <: i32) <: u8) <>! 6l <: i32) <: u8) - in - let coef11:u8 = cast (coefficient8 >>! 3l <: i32) <: u8 in -+ bit_vec_equal_intro_principle (); - coef1, coef2, coef3, coef4, coef5, coef6, coef7, coef8, coef9, coef10, coef11 - <: - (u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8) -+#pop-options + let encapsulate + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + = +- Libcrux.Kem.Kyber.encapsulate (sz 3) (sz 1088) (sz 1184) (sz 1152) (sz 960) (sz 128) (sz 10) ++ Libcrux.Kem.Kyber.encapsulate #Spec.Kyber.kyber768_params (sz 3) (sz 1088) (sz 1184) (sz 1152) (sz 960) (sz 128) (sz 10) + (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) public_key randomness --let compress_coefficients_3_ (coefficient1 coefficient2: u16) = -+#push-options "--z3rlimit 20" -+[@@"opaque_to_smt"] -+let compress_coefficients_3_ coefficient1 coefficient2 = - let coef1:u8 = cast (coefficient1 &. 255us <: u16) <: u8 in -+ get_bit_pow2_minus_one_u16 255 (sz 0); - let coef2:u8 = - cast ((coefficient1 >>! 8l <: u16) |. ((coefficient2 &. 15us <: u16) <>! 4l <: u16) &. 255us <: u16) <: u8 in -- coef1, coef2, coef3 <: (u8 & u8 & u8) -+ bit_vec_equal_intro_principle (); -+ coef1, coef2, coef3 <: (u8 & u8 & u8) -+#pop-options + Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) -+#push-options "--z3rlimit 160 --split_queries always" -+[@@"opaque_to_smt"] - let compress_coefficients_5_ -- (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: -- u8) +-let decapsulate_unpacked +- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 3)) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) - = -+ coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8 -+ = - let coef1:u8 = ((coefficient2 &. 7uy <: u8) <>! 4l <: u8) - in - let coef5:u8 = (coefficient8 <>! 2l <: u8) in -+ bit_vec_equal_intro_principle (); - coef1, coef2, coef3, coef4, coef5 <: (u8 & u8 & u8 & u8 & u8) -+#pop-options - --let decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: i32) = -+#push-options "--z3rlimit 500" -+[@@"opaque_to_smt"] -+let decompress_coefficients_10_ byte2 byte1 byte3 byte4 byte5 = - let coefficient1:i32 = ((byte2 &. 3l <: i32) <>! 2l <: i32) in - let coefficient3:i32 = ((byte4 &. 63l <: i32) <>! 4l <: i32) in - let coefficient4:i32 = (byte5 <>! 6l <: i32) in -- coefficient1, coefficient2, coefficient3, coefficient4 <: (i32 & i32 & i32 & i32) -+ lemma_get_bit_bounded' coefficient1 10; -+ lemma_get_bit_bounded' coefficient2 10; -+ lemma_get_bit_bounded' coefficient3 10; -+ lemma_get_bit_bounded' coefficient4 10; -+ bit_vec_equal_intro_principle (); -+ coefficient1, coefficient2, coefficient3, coefficient4 -+#pop-options +- Libcrux.Kem.Kyber.decapsulate_unpacked (sz 3) (sz 2400) (sz 1152) (sz 1184) (sz 1088) (sz 1152) +- (sz 960) (sz 128) (sz 10) (sz 4) (sz 320) (sz 2) (sz 128) (sz 2) (sz 128) (sz 1120) state +- ciphertext +- + let generate_key_pair (randomness: t_Array u8 (sz 64)) = +- Libcrux.Kem.Kyber.generate_keypair (sz 3) +- (sz 1152) +- (sz 2400) +- (sz 1184) +- (sz 1152) +- (sz 2) +- (sz 128) +- randomness +- +-let generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) = +- Libcrux.Kem.Kyber.generate_keypair_unpacked (sz 3) ++ Libcrux.Kem.Kyber.generate_keypair #Spec.Kyber.kyber768_params (sz 3) + (sz 1152) + (sz 2400) + (sz 1184) +diff -ruN extraction/Libcrux.Kem.Kyber.Kyber768.fsti extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti +--- extraction/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-14 15:56:45.395356991 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-14 15:56:45.451356072 +0200 +@@ -71,43 +71,25 @@ + unfold + let t_MlKem768PublicKey = Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184) -+#push-options "--z3rlimit 300" -+[@@"opaque_to_smt"] - let decompress_coefficients_11_ -- (byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11: i32) -- = -+ byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11 = - let coefficient1:i32 = ((byte2 &. 7l <: i32) <>! 3l <: i32) in - let coefficient3:i32 = -@@ -109,6 +137,15 @@ - in - let coefficient7:i32 = ((byte10 &. 31l <: i32) <>! 2l <: i32) in - let coefficient8:i32 = (byte11 <>! 5l <: i32) in -+ bit_vec_equal_intro_principle (); -+ lemma_get_bit_bounded' coefficient1 11; -+ lemma_get_bit_bounded' coefficient2 11; -+ lemma_get_bit_bounded' coefficient3 11; -+ lemma_get_bit_bounded' coefficient4 11; -+ lemma_get_bit_bounded' coefficient5 11; -+ lemma_get_bit_bounded' coefficient6 11; -+ lemma_get_bit_bounded' coefficient7 11; -+ lemma_get_bit_bounded' coefficient8 11; - coefficient1, - coefficient2, - coefficient3, -@@ -117,15 +154,22 @@ - coefficient6, - coefficient7, - coefficient8 -- <: -- (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) -+#pop-options +-/// Decapsulate ML-KEM 768 + val decapsulate + (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey (sz 2400)) + (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) ++ : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True ++ (ensures (fun res -> res == Spec.Kyber.kyber768_decapsulate secret_key.f_value ciphertext.f_value)) --let decompress_coefficients_4_ (byte: u8) = -+#push-options "--z3rlimit 50" -+[@@"opaque_to_smt"] -+let decompress_coefficients_4_ byte = - let coefficient1:i32 = cast (byte &. 15uy <: u8) <: i32 in - let coefficient2:i32 = cast ((byte >>! 4l <: u8) &. 15uy <: u8) <: i32 in -- coefficient1, coefficient2 <: (i32 & i32) -+ lemma_get_bit_bounded' coefficient1 4; -+ lemma_get_bit_bounded' coefficient2 4; -+ bit_vec_equal_intro_principle (); -+ coefficient1, coefficient2 -+#pop-options +-/// Encapsulate ML-KEM 768 + val encapsulate + (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) + (randomness: t_Array u8 (sz 32)) + : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True +- (fun _ -> Prims.l_True) ++ (ensures (fun (ct,ss)-> (ct.f_value,ss) == Spec.Kyber.kyber768_encapsulate public_key.f_value randomness)) --let decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: i32) = -+#push-options "--z3rlimit 400" -+[@@"opaque_to_smt"] -+let decompress_coefficients_5_ byte1 byte2 byte3 byte4 byte5 = - let coefficient1:i32 = byte1 &. 31l in - let coefficient2:i32 = ((byte2 &. 3l <: i32) <>! 5l <: i32) in - let coefficient3:i32 = (byte2 >>! 2l <: i32) &. 31l in -@@ -134,6 +178,15 @@ - let coefficient6:i32 = (byte4 >>! 1l <: i32) &. 31l in - let coefficient7:i32 = ((byte5 &. 7l <: i32) <>! 6l <: i32) in - let coefficient8:i32 = byte5 >>! 3l in -+ bit_vec_equal_intro_principle (); -+ lemma_get_bit_bounded' coefficient1 5; -+ lemma_get_bit_bounded' coefficient2 5; -+ lemma_get_bit_bounded' coefficient3 5; -+ lemma_get_bit_bounded' coefficient4 5; -+ lemma_get_bit_bounded' coefficient5 5; -+ lemma_get_bit_bounded' coefficient6 5; -+ lemma_get_bit_bounded' coefficient7 5; -+ lemma_get_bit_bounded' coefficient8 5; - coefficient1, - coefficient2, - coefficient3, -@@ -142,31 +195,54 @@ - coefficient6, - coefficient7, - coefficient8 -- <: -- (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) -+#pop-options +-/// Validate a public key. +-/// Returns `Some(public_key)` if valid, and `None` otherwise. + val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) + : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184))) + Prims.l_True + (fun _ -> Prims.l_True) + +-unfold +-let t_MlKem768State = Libcrux.Kem.Kyber.t_MlKemState (sz 3) +- +-val decapsulate_unpacked +- (state: Libcrux.Kem.Kyber.t_MlKemState (sz 3)) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088)) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +- +-/// Generate ML-KEM 768 Key Pair + val generate_key_pair (randomness: t_Array u8 (sz 64)) + : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair (sz 2400) (sz 1184)) + Prims.l_True +- (fun _ -> Prims.l_True) +- +-val generate_key_pair_unpacked (randomness: t_Array u8 (sz 64)) +- : Prims.Pure +- (Libcrux.Kem.Kyber.t_MlKemState (sz 3) & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ (ensures (fun kp -> (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.kyber768_generate_keypair randomness)) +diff -ruN extraction/Libcrux.Kem.Kyber.Matrix.fst extraction-edited/Libcrux.Kem.Kyber.Matrix.fst +--- extraction/Libcrux.Kem.Kyber.Matrix.fst 2024-05-14 15:56:45.407356794 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Matrix.fst 2024-05-14 15:56:45.428356450 +0200 +@@ -3,192 +3,188 @@ + open Core + open FStar.Mul + +-let compute_As_plus_e +- (v_K: usize) +- (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- = +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__iter (Rust_primitives.unsize matrix_A +- <: +- t_Slice (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- <: +- Core.Slice.Iter.t_Iter +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) ++open Libcrux.Kem.Kyber.Arithmetic ++ ++let op_Array_Access (x:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) (i:usize{v i < 256}): i32 = ++ x.f_coefficients.[i] ++ ++ ++#push-options "--ifuel 0 --z3rlimit 700" ++let compute_As_plus_e v_K matrix_A s_as_ntt error_as_ntt = ++ let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in ++ let result:t_Array wfPolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat wfZero v_K ++ in ++ [@ inline_let] ++ let inv0 = fun (acc:t_Array wfPolynomialRingElement v_K) (i:usize) -> ++ (v i <= v v_K) /\ ++ (forall (j:usize). (v j >= v i /\ v j < v v_K) ==> (acc.[j] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) == wfZero) ++ in ++ assert (inv0 result (sz 0)); ++ let result:t_Array wfPolynomialRingElement v_K = ++ Rust_primitives.Iterators.foldi_slice #(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) #(t_Array wfPolynomialRingElement v_K) #inv0 ++ matrix_A + result + (fun result temp_1_ -> +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = result in +- let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = ++ let orig_result = result in ++ let orig_result_cast = (cast_vector_b #v_K #3328 #(v v_K * 3328) orig_result) in ++ let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = + temp_1_ + in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__iter (Rust_primitives.unsize row +- <: +- t_Slice Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) +- result ++ [@ inline_let] ++ let inv1 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) (inner:usize) -> ++ (v inner <= v v_K) /\ ++ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (poly_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) (v inner * 3328)) ++ in ++ assert (forall (k:usize). (v k < 256) ==> v (result.[i] <: wfPolynomialRingElement).f_coefficients.[k] == 0); ++ assert(inv1 orig_result_cast (sz 0)); ++ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = ++ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) #inv1 ++ row ++ orig_result_cast + (fun result temp_1_ -> +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- result +- in + let j, matrix_element:(usize & +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = + temp_1_ + in +- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let resulti = down_cast_poly_b #(v v_K * 3328) #(v j * 3328) result.[i] in ++ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + Libcrux.Kem.Kyber.Ntt.ntt_multiply matrix_element +- (s_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (s_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ let product_sum:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v j + 1) * 3328) = ++ (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element #(v j * 3328) #3328 v_K ++ resulti ++ product) in ++ let product_sum:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) = cast_poly_b #((v j+1)* 3328) #(v v_K * 3328) product_sum in ++ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i +- (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K +- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- product +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ product_sum + in + result) + in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end +- = +- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) ++ let result1 = result in ++ [@ inline_let] ++ let inv2 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) (inner:usize) -> ++ (v inner <= 256) /\ ++ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (forall (j:usize). (v j < v inner) ==> (i32_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)).f_coefficients.[j] 3328)) ++ // And all indexes above v inner are unchanged from result1 ++ in ++ assert (inv2 result1 (sz 0)); ++ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = ++ Rust_primitives.Iterators.foldi_range #_ #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K) #inv2 { ++ Core.Ops.Range.f_start = sz 0; ++ Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT ++ } + result +- (fun result j -> +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- result +- in ++ (fun result j -> ++ let result: t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K = result in + let j:usize = j in +- let coefficient_normal_form:i32 = +- Libcrux.Kem.Kyber.Arithmetic.to_standard_domain ((result.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] +- <: +- i32) ++ let resulti:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) = result.[ i ] <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) in ++ let coefficient_normal_form: i32_b ((nat_div_ceil (v v_K * 3328 * 1353) (pow2 16)) + 1665) = ++ Libcrux.Kem.Kyber.Arithmetic.to_standard_domain #(v v_K * 3328) (resulti ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ]) + in ++ assert ((nat_div_ceil (v v_K * 3328 * 1353) (pow2 16)) + 1665 <= 1940); ++ let coefficient_normal_form: i32_b 1940 = cast_i32_b #((nat_div_ceil (v v_K * 3328 * 1353) (pow2 16)) + 1665) #1940 coefficient_normal_form in ++ let x1: i32_b 3328 = (error_as_ntt.[ i ] ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] in ++ let x2: i32_b 5268 = add_i32_b coefficient_normal_form x1 in ++ assert (5268 <= v v_BARRETT_R /\ v v_BARRETT_R < pow2 31); ++ let x3: i32_b (v v_BARRETT_R) = cast_i32_b #5268 #(v v_BARRETT_R) x2 in ++ let resultij: i32_b 3328 = Libcrux.Kem.Kyber.Arithmetic.barrett_reduce x3 in ++ let resultij: i32_b (v v_K * 3328) = cast_i32_b #3328 #(v v_K * 3328) resultij in ++ let resulti_coeffs = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize ++ (resulti.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) ++ j resultij in ++ let result = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + ({ +- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with ++ resulti with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (result.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- j +- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (coefficient_normal_form +! +- ((error_as_ntt.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] +- <: +- i32) +- <: +- i32) +- <: +- i32) +- <: +- t_Array i32 (sz 256) ++ = resulti_coeffs + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement))) +- in +- result ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K*3328)) in ++ assert ((result.[i]).f_coefficients.[j] == resultij); ++ assert(inv2 result (j +! sz 1)); ++ let result: x:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) v_K{inv2 x (j +! mk_int 1)} = result in ++ result) in ++ assert (v i + 1 < v v_K ==> result.[i +! sz 1] == orig_result_cast.[i +! sz 1]); ++ let result: t_Array wfPolynomialRingElement v_K = ++ down_cast_vector_b #v_K #(v v_K * 3328) #3328 result in ++ assert (forall (j:usize). (v j >= v i + 1 /\ v j < v v_K) ==> derefine_poly_b result.[j] == derefine_poly_b orig_result.[j]); ++ assume (inv0 result (i +! sz 1)); ++ result) ++ in ++ admit(); //P-F ++ result ++#pop-options -+let cast_bound_lemma -+ #t #u -+ (n: int_t t) -+ (d: num_bits t) -+ : Lemma (requires bounded n d /\ d <= bits u /\ unsigned u /\ v n >= 0) -+ (ensures bounded (cast #(int_t t) #(int_t u) n) d) -+ [SMTPat (bounded n d); SMTPat (cast #(int_t t) #(int_t u) n)] -+ = () -+ -+#push-options "--z3rlimit 90" -+[@@"opaque_to_smt"] -+let int_t_d_cast_lemma #t #u d (n: int_t_d t d) -+ : Lemma (requires bits t < bits u /\ v n >= 0) -+ (ensures bounded (cast #(int_t t) #(int_t u) n) d) -+ [SMTPat (bounded (cast #(int_t t) #(int_t u) n) d)] -+ = Math.Lemmas.pow2_double_mult (bits u - 1); -+ Math.Lemmas.small_mod (v n) (modulus u) -+let mul_in_range (n m: nat) -+ : Lemma -+ (requires n <= 256 /\ m <= 256) -+ (ensures range (n * m) usize_inttype) -+ = Math.Lemmas.pow2_plus 8 8; -+ Math.Lemmas.pow2_le_compat 32 16 -+#pop-options -+ -+#restart-solver -+ -+#push-options "--fuel 0 --ifuel 1 --query_stats --z3rlimit 100" -+[@@"opaque_to_smt"] - let compress_then_serialize_10_ -- (v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +-let compute_message +- (v_K: usize) +- (v: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (secret_as_ntt u_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) - = -+ v_OUT_LEN -+ re -+ = -+ let accT = t_Array u8 v_OUT_LEN in -+ let inv = fun (acc: t_Array u8 v_OUT_LEN) (i: usize) -> -+ True +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++#push-options "--ifuel 0 --z3rlimit 100" ++let compute_message #p v_K m_v secret_as_ntt u_as_ntt = ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in - let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in - let serialized:t_Array u8 v_OUT_LEN = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- (sz 4) -- <: -- Core.Slice.Iter.t_ChunksExact i32) ++ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> ++ (v i <= v v_K) /\ ++ (poly_range #(v v_K * 3328) acc (v i * 3328)) + in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = ++ Rust_primitives.Iterators.foldi_range #_ #acc_t #inv { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = v_K + } - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- Core.Ops.Range.t_Range usize) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -- serialized -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #accT #inv -+ (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) -+ (sz 4) -+ (serialized) - (fun serialized temp_1_ -> - let serialized:t_Array u8 v_OUT_LEN = serialized in -- let i, coefficients:(usize & t_Slice i32) = temp_1_ in -+ let i, coefficients:(usize & _) = temp_1_ in - let coefficient1:i32 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 10uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] <: i32 -@@ -226,79 +302,96 @@ - serialized) +- Core.Ops.Range.t_Range usize) +- result ++ result + (fun result i -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in + let i:usize = i in +- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let result:t_PolynomialRingElement_b (v i * 3328) = ++ down_cast_poly_b #(v v_K * 3328) #(v i * 3328) result in ++ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + Libcrux.Kem.Kyber.Ntt.ntt_multiply (secret_as_ntt.[ i ] + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (u_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (u_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v i+1) * 3328) = + Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K result product + in ++ let result = cast_poly_b #((v i + 1) * 3328) #(v v_K * 3328) result in ++ assert(inv result (i +! sz 1)); + result) + in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K result ++ let acc_t = t_PolynomialRingElement_b (64*v v_K*3328) in ++ let result:acc_t = Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K result + in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> ++ (v i <= 256) /\ ++ (forall (j:usize). (v j < v i) ==> i32_range ((acc <: t_PolynomialRingElement_b (64* v v_K * 3328)).f_coefficients.[j]) 3328) in ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K*3328) = ++ Rust_primitives.Iterators.foldi_range #_ #_ #inv { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- result ++ result + (fun result i -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in + let i:usize = i in +- let coefficient_normal_form:i32 = +- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) *! +- 1441l +- <: +- i32) +- in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- { +- result with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- i +- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((v ++ let coefficient_normal_form: i32_b (nat_div_ceil (306921472*v v_K) 65536 + 1665) = ++ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ++ (Libcrux.Kem.Kyber.Arithmetic.mul_i32_b #(64 * v v_K * 3328) #1441 ++ result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] ++ (1441l <: Libcrux.Kem.Kyber.Arithmetic.i32_b 1441)) in ++ let resulti : i32_b 3328 = (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((m_v + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] + <: + i32) -! +@@ -196,81 +192,77 @@ + <: + i32) + <: +- i32) ++ i32) in ++ let resulti = cast_i32_b #3328 #(64*v v_K*3328) resulti in ++ let result = ++ { ++ result with ++ Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ i resulti + } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement + in ++ assert (inv result (i +! sz 1)); + result) in - serialized ++ admit(); //P-F + result +#pop-options -+#push-options "--fuel 0 --ifuel 0 --z3rlimit 30" -+[@@"opaque_to_smt"] -+let update5 -+ #n -+ (s: t_Array 't n) -+ (offset: usize {v offset + 5 <= v n}) -+ (i0 i1 i2 i3 i4: 't) -+ : s': t_Array 't n { -+ Seq.index s' (v offset + 0) == i0 /\ -+ Seq.index s' (v offset + 1) == i1 /\ -+ Seq.index s' (v offset + 2) == i2 /\ -+ Seq.index s' (v offset + 3) == i3 /\ -+ Seq.index s' (v offset + 4) == i4 /\ -+ (forall i. (i < v offset \/ i >= v offset + 5) ==> Seq.index s' i == Seq.index s i) -+ } -+ = let open Rust_primitives.Hax.Monomorphized_update_at in -+ let s = update_at_usize s offset i0 in -+ let s = update_at_usize s (offset +! sz 1) i1 in -+ let s = update_at_usize s (offset +! sz 2) i2 in -+ let s = update_at_usize s (offset +! sz 3) i3 in -+ let s = update_at_usize s (offset +! sz 4) i4 in -+ s -+#pop-options -+ -+#push-options "--fuel 0 --ifuel 1 --z3rlimit 100 --query_stats --split_queries no" - let compress_then_serialize_11_ -- (v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +-let compute_ring_element_v +- (v_K: usize) +- (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (error_2_ message: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) - = -+ v_OUT_LEN re -+ = -+ let inv = fun (acc: t_Array u8 v_OUT_LEN) (i: usize) -> True in - let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in - let serialized:t_Array u8 v_OUT_LEN = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- (sz 8) -- <: -- Core.Slice.Iter.t_ChunksExact i32) +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO +- in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++#push-options "--ifuel 0 --z3rlimit 100" ++let compute_ring_element_v v_K tt_as_ntt r_as_ntt error_2_ message = ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ in ++ [@ inline_let] ++ let inv = fun (acc:t_PolynomialRingElement_b (v v_K * 3328)) (i:usize) -> ++ (v i <= 256) /\ ++ (poly_range acc (v i * 3328)) in ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = ++ Rust_primitives.Iterators.foldi_range #_ #_ #inv ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = v_K + } - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv -+ (Rust_primitives.unsize re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) -+ (sz 8) - serialized - (fun serialized temp_1_ -> - let serialized:t_Array u8 v_OUT_LEN = serialized in -- let i, coefficients:(usize & t_Slice i32) = temp_1_ in -- let coefficient1:i32 = -+ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement (sz 8)) = temp_1_ in -+ let coefficient1 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] <: i32 - ) - <: - u16) - in -- let coefficient2:i32 = -+ let coefficient2 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 1 ] <: i32 - ) - <: - u16) - in -- let coefficient3:i32 = -+ let coefficient3 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 2 ] <: i32 - ) - <: - u16) - in -- let coefficient4:i32 = -+ let coefficient4 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 3 ] <: i32 - ) - <: - u16) - in -- let coefficient5:i32 = -+ let coefficient5 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 4 ] <: i32 - ) - <: - u16) - in -- let coefficient6:i32 = -+ let coefficient6 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 5 ] <: i32 - ) +- Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) + result + (fun result i -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- let i:usize = i in +- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + Libcrux.Kem.Kyber.Ntt.ntt_multiply (tt_as_ntt.[ i ] <: - u16) +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (r_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (r_as_ntt.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) in -- let coefficient7:i32 = -+ let coefficient7 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 6 ] <: i32 - ) - <: - u16) +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let result:t_PolynomialRingElement_b (v i * 3328) = ++ down_cast_poly_b #(v v_K * 3328) #(v i * 3328) result in ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v i + 1) * 3328) = + Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K result product in -- let coefficient8:i32 = -+ let coefficient8 = - Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 7 ] <: i32 - ) -@@ -324,6 +417,8 @@ - coefficient7 - coefficient8 +- result) ++ cast_poly_b result) + in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) = + Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K result + in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ [@ inline_let] ++ let inv = fun (acc:t_PolynomialRingElement_b (64 * v v_K * 3328)) (i:usize) -> ++ (v i <= 256) /\ ++ (forall (j:usize). (v j < v i) ==> i32_range ((acc <: t_PolynomialRingElement_b (64* v v_K * 3328)).f_coefficients.[j]) 3328) in ++ let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) = ++ Rust_primitives.Iterators.foldi_range #_ #_ #inv { + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- result ++ result + (fun result i -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- let i:usize = i in +- let coefficient_normal_form:i32 = +- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) *! +- 1441l +- <: +- i32) +- in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- { +- result with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- i +- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((coefficient_normal_form +! ++ let coefficient_normal_form: i32_b (nat_div_ceil (306921472*v v_K) 65536 + 1665) = ++ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ++ (Libcrux.Kem.Kyber.Arithmetic.mul_i32_b #(64 * v v_K * 3328) #1441 ++ result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] ++ (1441l <: Libcrux.Kem.Kyber.Arithmetic.i32_b 1441)) in ++ let resulti : i32_b 3328 = ++ (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ((coefficient_normal_form +! + (error_2_.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] <: i32) + <: + i32) +! +@@ -278,157 +270,151 @@ + <: + i32) + <: +- i32) ++ i32) in ++ let resulti = cast_i32_b #3328 #(64*v v_K*3328) resulti in ++ let result = ++ { ++ result with ++ Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ i resulti + } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement in -+ assert_spinoff (v i < 32 ==> 11 * v i + 11 <= 32 * 11); -+ assert_spinoff (v i < 32 ==> range (v (sz 11) * v i) usize_inttype); - let serialized:t_Array u8 v_OUT_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized - (sz 11 *! i <: usize) -@@ -382,29 +477,20 @@ - serialized) + result) in - serialized ++ admit(); //P-F + result +#pop-options --let compress_then_serialize_4_ -- (v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++#push-options "--ifuel 0 --z3rlimit 300" + let compute_vector_u + (v_K: usize) +- (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) - = -+let compress_then_serialize_4_ v_OUT_LEN re = - let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in -+ let accT = t_Array u8 v_OUT_LEN in -+ let inv (acc: accT) (i: usize) = True in - let serialized:t_Array u8 v_OUT_LEN = +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- (Core.Slice.impl__iter (Rust_primitives.unsize a_as_ntt - <: -- t_Slice i32) -- (sz 2) +- t_Slice (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) - <: -- Core.Slice.Iter.t_ChunksExact i32) +- Core.Slice.Iter.t_Iter +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K)) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv -+ (Rust_primitives.unsize re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) -+ (sz 2) - serialized - (fun serialized temp_1_ -> - let serialized:t_Array u8 v_OUT_LEN = serialized in -- let i, coefficients:(usize & t_Slice i32) = temp_1_ in -+ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement (sz 2)) = temp_1_ in - let coefficient1:u8 = - cast (Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 4uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] -@@ -439,27 +525,20 @@ - serialized - - let compress_then_serialize_5_ -- (v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- = -+ v_OUT_LEN -+ re -+ = - let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in -+ let accT = t_Array u8 v_OUT_LEN in -+ let inv (acc: accT) (i: usize) = True in - let serialized:t_Array u8 v_OUT_LEN = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K))) ++ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) ++ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = ++ let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in ++ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat wfZero v_K ++ in ++ let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in ++ [@ inline_let] ++ let inv0 = fun (acc:t_Array wfPolynomialRingElement v_K) (i:usize) -> ++ (v i <= v v_K) /\ ++ (forall (j:usize). (v j >= v i /\ v j < v v_K) ==> (acc.[j] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) == wfZero) ++ in ++ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = ++ Rust_primitives.Iterators.foldi_slice #(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) #acc_t #inv0 ++ a_as_ntt + result + (fun result temp_1_ -> +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = result in +- let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = ++ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = result in ++ let orig_result = result in ++ let orig_result_cast = (cast_vector_b #v_K #3328 #(64 * v v_K * 3328) orig_result) in ++ let i, row:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) = + temp_1_ + in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__iter (Rust_primitives.unsize row +- <: +- t_Slice Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) - <: -- t_Slice i32) -- (sz 8) +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) - <: -- Core.Slice.Iter.t_ChunksExact i32) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv -+ (Rust_primitives.unsize re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) -+ (sz 8) - serialized - (fun serialized temp_1_ -> - let serialized:t_Array u8 v_OUT_LEN = serialized in -- let i, coefficients:(usize & t_Slice i32) = temp_1_ in -+ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement (sz 8)) = temp_1_ in - let coefficient1:u8 = - cast (Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 5uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] -@@ -544,6 +623,14 @@ - <: - u8 - in -+ let coefficient8' = Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 5uy -+ (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 7 ] -+ <: -+ i32) -+ <: -+ u16) -+ <: -+ i32 in - let coefficient8:u8 = - cast (Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 5uy - (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 7 ] -@@ -566,6 +653,8 @@ - coefficient6 - coefficient8 +- Core.Iter.Adapters.Enumerate.t_Enumerate +- (Core.Slice.Iter.t_Iter Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement)) +- result ++ [@ inline_let] ++ let inv1 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K) (inner:usize) -> ++ (v inner <= v v_K) /\ ++ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (poly_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) (v inner * 3328)) ++ in ++ assert (forall (k:usize). (v k < 256) ==> v (result.[i] <: wfPolynomialRingElement).f_coefficients.[k] == 0); ++ assert(inv1 orig_result_cast (sz 0)); ++ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K = ++ Rust_primitives.Iterators.foldi_slice #Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K) #inv1 ++ row ++ orig_result_cast + (fun result temp_1_ -> +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- result +- in +- let j, a_element:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let j, a_element:(usize & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = + temp_1_ + in +- let product:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let resulti = down_cast_poly_b #(64 * v v_K * 3328) #(v j * 3328) result.[i] in ++ let product:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + Libcrux.Kem.Kyber.Ntt.ntt_multiply a_element +- (r_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (r_as_ntt.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ let product_sum:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b ((v j + 1) * 3328) = ++ (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element #(v j * 3328) #3328 v_K ++ resulti ++ product) in ++ let product_sum:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) = cast_poly_b #((v j+1)* 3328) #(64 * v v_K * 3328) product_sum in ++ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328)) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i +- (Libcrux.Kem.Kyber.Arithmetic.add_to_ring_element v_K +- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- product +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ product_sum + in + result) in -+ assert_spinoff (v i < 32 ==> 5 * v i + 5 <= 32 * 5); -+ assert_spinoff (v i < 32 ==> range (v (sz 5) * v i) usize_inttype); - let serialized:t_Array u8 v_OUT_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized - (sz 5 *! i <: usize) -@@ -595,35 +684,24 @@ +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ assert (forall (j:usize). (v j < v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); ++ assert (forall (j:usize). (v j > v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); ++ let resulti : t_PolynomialRingElement_b (v v_K * 3328) = down_cast_poly_b result.[i] in ++ let result = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i +- (Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K +- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end +- = +- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) ++ (Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K resulti) ++ in ++ [@ inline_let] ++ let inv2 = fun (acc:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K) (inner:usize) -> ++ (v inner <= 256) /\ ++ (forall (j:usize). (v j < v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ ++ (forall (j:usize). (v j < v inner) ==> (i32_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)).f_coefficients.[j] 3328)) ++ // And all indexes above v inner are unchanged from result1 ++ in ++ assert (forall (j:usize). (v j < v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); ++ assert (forall (j:usize). (v j > v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); ++ assert (inv2 result (sz 0)); ++ let result:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K = ++ Rust_primitives.Iterators.foldi_range #_ #(t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K) #inv2 { ++ Core.Ops.Range.f_start = sz 0; ++ Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT ++ } + result + (fun result j -> +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- result +- in +- let j:usize = j in +- let coefficient_normal_form:i32 = +- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (((result.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] +- <: +- i32) *! +- 1441l +- <: +- i32) +- in +- let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ let result: t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) v_K = result in ++ let resulti:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) = result.[ i ] <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)) in ++ let coefficient_normal_form: i32_b (nat_div_ceil (306921472*v v_K) 65536 + 1665) = ++ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ++ (Libcrux.Kem.Kyber.Arithmetic.mul_i32_b #(64 * v v_K * 3328) #1441 ++ (resulti <: t_PolynomialRingElement_b (64*v v_K * 3328)).f_coefficients.[j] (1441l <: Libcrux.Kem.Kyber.Arithmetic.i32_b 1441)) in ++ let resultij: i32_b 3328 = (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce ++ (add_i32_b coefficient_normal_form ((error_1_.[ i ] ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ]))) in ++ let result = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize result + i + ({ +- (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with ++ resulti with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients + = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (result.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (resulti ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients) + j +- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (coefficient_normal_form +! +- ((error_1_.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] +- <: +- i32) +- <: +- i32) +- <: +- i32) +- <: +- t_Array i32 (sz 256) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- in +- result)) ++ (cast_i32_b #3328 #(64 * v v_K * 3328) resultij) ++ }) in ++ result) ++ in ++ let result: t_Array wfPolynomialRingElement v_K = ++ down_cast_vector_b #v_K #(64 * v v_K * 3328) #3328 result in ++ assert (forall (j:usize). (v j >= v i + 1 /\ v j < v v_K) ==> derefine_poly_b result.[j] == derefine_poly_b orig_result.[j]); ++ assume (inv0 result (i +! sz 1)); ++ result) in - serialized ++ admit(); //P-F + result ++#pop-options --let compress_then_serialize_message (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -+let compress_then_serialize_message re = - let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in -+ let accT = t_Array u8 (sz 32) in -+ let inv (acc: accT) (i: usize) = True in - let serialized:t_Array u8 (sz 32) = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- <: -- t_Slice i32) -- (sz 8) -- <: -- Core.Slice.Iter.t_ChunksExact i32) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) + let sample_matrix_A (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) = +- let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = +- Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO +- v_K - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv -+ (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) -+ (sz 8) - serialized - (fun serialized temp_1_ -> - let serialized:t_Array u8 (sz 32) = serialized in -- let i, coefficients:(usize & t_Slice i32) = temp_1_ in -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__iter coefficients <: Core.Slice.Iter.t_Iter i32) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter i32)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter i32)) -+ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement _) = temp_1_ in -+ Rust_primitives.Iterators.foldi_slice #_ #_ #(fun _ _ -> True) -+ coefficients - serialized - (fun serialized temp_1_ -> - let serialized:t_Array u8 (sz 32) = serialized in -- let j, coefficient:(usize & i32) = temp_1_ in -+ let j, coefficient:(usize & Libcrux.Kem.Kyber.Arithmetic.wfFieldElement) = temp_1_ in - let coefficient:u16 = - Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative coefficient +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- v_K ++ let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in ++ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = ++ Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat wfZero v_K) v_K + in +- let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = ++ let v_A_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = v_K +@@ -440,7 +426,7 @@ + v_A_transpose + (fun v_A_transpose i -> + let v_A_transpose:t_Array +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = ++ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = + v_A_transpose + in + let i:usize = i in +@@ -482,8 +468,8 @@ + in + seeds) + in +- let sampled:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Libcrux.Kem.Kyber.Sampling.sample_from_xof v_K seeds ++ let xof_bytes:t_Array (t_Array u8 (sz 840)) v_K = ++ Libcrux.Kem.Kyber.Hash_functions.v_XOFx4 v_K seeds + in + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; +@@ -496,40 +482,46 @@ + v_A_transpose + (fun v_A_transpose j -> + let v_A_transpose:t_Array +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = ++ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = + v_A_transpose in -@@ -636,27 +714,35 @@ - <: - t_Array u8 (sz 32)) + let j:usize = j in ++ let sampled:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Sampling.sample_from_uniform_distribution (xof_bytes.[ j ] ++ <: ++ t_Array u8 (sz 840)) ++ in + if transpose + then + let v_A_transpose:t_Array +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = ++ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v_A_transpose + j + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (v_A_transpose.[ j + ] + <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) + i +- (sampled.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ sampled + <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) + in + v_A_transpose + else + let v_A_transpose:t_Array +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = ++ (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize v_A_transpose + i + (Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (v_A_transpose.[ i + ] + <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) + j +- (sampled.[ j ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ sampled + <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) + in + v_A_transpose)) in -+ admit (); // P-F - serialized ++ admit(); //P-F + v_A_transpose +diff -ruN extraction/Libcrux.Kem.Kyber.Matrix.fsti extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti +--- extraction/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-14 15:56:45.400356909 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-14 15:56:45.462355892 +0200 +@@ -3,46 +3,71 @@ + open Core + open FStar.Mul + +-/// Compute  ◦ ŝ + ê +-val compute_As_plus_e ++ ++val compute_As_plus_e (#p:Spec.Kyber.params) + (v_K: usize) +- (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// The following functions compute various expressions involving +-/// vectors and matrices. The computation of these expressions has been +-/// abstracted away into these functions in order to save on loop iterations. +-/// Compute v − InverseNTT(sᵀ ◦ NTT(u)) +-val compute_message ++ (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) ++ (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (requires (v_K == p.v_RANK)) ++ (ensures fun res -> ++ let open Libcrux.Kem.Kyber.Arithmetic in ++ v_K == p.v_RANK /\ ++ to_spec_vector_b #p res = ++ Spec.Kyber.compute_As_plus_e #p ++ (to_spec_matrix_b #p matrix_A) ++ (to_spec_vector_b #p s_as_ntt) ++ (to_spec_vector_b #p error_as_ntt)) ++ ++ ++val compute_message (#p:Spec.Kyber.params) + (v_K: usize) +- (v: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (secret_as_ntt u_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) ++ (poly_v: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (secret_as_ntt u_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires (v_K == p.v_RANK)) ++ (ensures (fun res -> ++ let secret_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p secret_as_ntt in ++ let u_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p u_as_ntt in ++ let v_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b poly_v in ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res == ++ Spec.Kyber.(poly_sub v_spec (poly_inv_ntt #p (vector_dot_product secret_spec u_spec))))) + +-/// Compute InverseNTT(tᵀ ◦ r̂) + e₂ + message +-val compute_ring_element_v ++// TODO: error_2_ changed from `t_PolynomialRingElement_b 3` to `t_PolynomialRingElement_b 7` ++val compute_ring_element_v (#p:Spec.Kyber.params) + (v_K: usize) +- (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- (error_2_ message: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) ++ (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (error_2_: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7) ++ (message: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires (v_K == p.v_RANK)) ++ (ensures fun res -> ++ let tt_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p tt_as_ntt in ++ let r_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p r_as_ntt in ++ let e2_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b error_2_ in ++ let m_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b message in ++ let res_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res in ++ res_spec == Spec.Kyber.(poly_add (poly_add (vector_dot_product tt_spec r_spec) e2_spec) m_spec)) --let compress_then_serialize_ring_element_u -- (v_COMPRESSION_FACTOR v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- = -+let compress_then_serialize_ring_element_u #p -+ v_COMPRESSION_FACTOR -+ v_OUT_LEN -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = - let _:Prims.unit = () <: Prims.unit in -+ assert ( -+ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 11) \/ -+ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 10) -+ ); -+ Rust_primitives.Integers.mk_int_equiv_lemma #usize_inttype (v v_COMPRESSION_FACTOR); - match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 10ul -> compress_then_serialize_10_ v_OUT_LEN re - | 11ul -> compress_then_serialize_11_ v_OUT_LEN re - | _ -> - Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" +-/// Compute u := InvertNTT(Aᵀ ◦ r̂) + e₁ +-val compute_vector_u ++val compute_vector_u (#p:Spec.Kyber.params) + (v_K: usize) +- (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) - - <: - Rust_primitives.Hax.t_Never) +-val sample_matrix_A (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) +- : Prims.Pure (t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) ++ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) ++ (requires (v_K == p.v_RANK)) ++ (ensures fun res -> ++ let a_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p a_as_ntt in ++ let r_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p r_as_ntt in ++ let e_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p error_1_ in ++ let res_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res in ++ res_spec == Spec.Kyber.(vector_add (vector_inv_ntt (matrix_vector_mul a_spec r_spec)) e_spec)) ++ ++ ++ ++val sample_matrix_A (#p:Spec.Kyber.params) (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) ++ : Pure (t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) v_K) ++ (requires (v_K == p.v_RANK)) ++ (ensures fun res -> ++ let matrix_A = Spec.Kyber.sample_matrix_A #p (Seq.slice seed 0 32) in ++ if transpose then Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p res == matrix_A ++ else Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p res == Spec.Kyber.matrix_transpose matrix_A) +diff -ruN extraction/Libcrux.Kem.Kyber.Ntt.fst extraction-edited/Libcrux.Kem.Kyber.Ntt.fst +--- extraction/Libcrux.Kem.Kyber.Ntt.fst 2024-05-14 15:56:45.398356942 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Ntt.fst 2024-05-14 15:56:45.431356400 +0200 +@@ -1,56 +1,130 @@ + module Libcrux.Kem.Kyber.Ntt +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" + open Core + open FStar.Mul --let compress_then_serialize_ring_element_v -- (v_COMPRESSION_FACTOR v_OUT_LEN: usize) +-let ntt_multiply_binomials (a0, a1: (i32 & i32)) (b0, b1: (i32 & i32)) (zeta: i32) = +- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b0 <: i32) +! +- ((Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (a1 *! b1 <: i32) <: i32) *! zeta <: i32) +- <: +- i32), +- Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b1 <: i32) +! (a1 *! b0 <: i32) <: i32) +- <: +- (i32 & i32) +- +-let invert_ntt_at_layer +- (zeta_i: usize) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer: usize) - = -+let compress_then_serialize_ring_element_v #p v_COMPRESSION_FACTOR v_OUT_LEN re = - let _:Prims.unit = () <: Prims.unit in -+ Rust_primitives.Integers.mk_int_equiv_lemma #usize_inttype (v v_COMPRESSION_FACTOR); -+ let res = -+ assert ( -+ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 4) \/ -+ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 5) -+ ); - match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 4ul -> compress_then_serialize_4_ v_OUT_LEN re - | 5ul -> compress_then_serialize_5_ v_OUT_LEN re -@@ -665,32 +751,49 @@ - - <: - Rust_primitives.Hax.t_Never) ++ ++let v_ZETAS_TIMES_MONTGOMERY_R = ++ let list : list (i32_b 1664) = ++ [ ++ (-1044l); (-758l); (-359l); (-1517l); 1493l; 1422l; 287l; 202l; (-171l); 622l; 1577l; 182l; ++ 962l; (-1202l); (-1474l); 1468l; 573l; (-1325l); 264l; 383l; (-829l); 1458l; (-1602l); (-130l); ++ (-681l); 1017l; 732l; 608l; (-1542l); 411l; (-205l); (-1571l); 1223l; 652l; (-552l); 1015l; ++ (-1293l); 1491l; (-282l); (-1544l); 516l; (-8l); (-320l); (-666l); (-1618l); (-1162l); 126l; ++ 1469l; (-853l); (-90l); (-271l); 830l; 107l; (-1421l); (-247l); (-951l); (-398l); 961l; ++ (-1508l); (-725l); 448l; (-1065l); 677l; (-1275l); (-1103l); 430l; 555l; 843l; (-1251l); 871l; ++ 1550l; 105l; 422l; 587l; 177l; (-235l); (-291l); (-460l); 1574l; 1653l; (-246l); 778l; 1159l; ++ (-147l); (-777l); 1483l; (-602l); 1119l; (-1590l); 644l; (-872l); 349l; 418l; 329l; (-156l); ++ (-75l); 817l; 1097l; 603l; 610l; 1322l; (-1285l); (-1465l); 384l; (-1215l); (-136l); 1218l; ++ (-1335l); (-874l); 220l; (-1187l); (-1659l); (-1185l); (-1530l); (-1278l); 794l; (-1510l); ++ (-854l); (-870l); 478l; (-108l); (-308l); 996l; 991l; 958l; (-1460l); 1522l; 1628l ++ ] + in -+ admit (); // P-F ++ FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 128); ++ FStar.Pervasives.assert_norm (List.Tot.index list 1 == -758l); ++ Seq.of_list list ++ ++open Libcrux.Kem.Kyber.Arithmetic ++ ++#push-options "--z3rlimit 50" ++let ntt_multiply_binomials (a0,a1) (b0,b1) zeta = ++ let r0 = montgomery_reduce (mul_i32_b a1 b1) in ++ let res = ++ montgomery_reduce (add_i32_b (mul_i32_b a0 b0) (mul_i32_b r0 zeta)), ++ montgomery_reduce (add_i32_b (mul_i32_b a0 b1) (mul_i32_b a1 b0)) in + res ++#pop-options ++ ++val mul_zeta_red (#v_K:usize{v v_K >= 1 /\ v v_K <= 4}) ++ (#b:nat{b <= v v_K * 3328 * 64}) ++ (zeta_i:usize{v zeta_i > 0 /\ v zeta_i <= 128} ) ++ (layer:usize{v layer > 0 /\ ++ v layer <= 7 /\ ++ v zeta_i == pow2 (8 - v layer) /\ ++ b == v v_K * 3328 * pow2(v layer - 1)}) ++ (x:i32_b (2*b)) ++ (i:usize{v i < 128 / pow2 (v layer)}) : ++ i32_b (2*b) ++let mul_zeta_red #v_K #b zeta_i layer x i = ++ let zeta_i = zeta_i -! sz 1 -! i in ++ let zeta:i32_b 1664 = v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] in ++ if layer <=. sz 6 then ( ++ assert (b <= 4 * 3328 * 32); ++ assert (2*b*1664 < pow2 31); ++ let product:i32_b (2 * b * 1664) = mul_i32_b x zeta in ++ let res = montgomery_reduce product in ++ res ++ ) else ( ++ assert (v i < 1); ++ assert (zeta_i = sz 1); ++ assert (zeta = -758l); ++ let zeta:i32_b 758 = zeta in ++ let product:i32_b (2 * b * 758) = mul_i32_b x zeta in ++ let res = montgomery_reduce product in ++ res ++ ) ++ ++ ++val lemma_zeta_decr: orig:usize -> fin:usize -> layer:usize{v layer <= 7} -> ++ Lemma (v fin == v orig - 128/(pow2 (v layer)) /\ ++ v orig == pow2 (8 - v layer) ==> ++ v fin == pow2 (7 - v layer)) ++let lemma_zeta_decr orig fin layer = () ++ ++#push-options "--ifuel 0 --z3rlimit 1200" ++let invert_ntt_at_layer #v_K #b zeta_i re layer = + let step:usize = sz 1 < 0); ++ assert (v step == pow2 (v layer)); ++ let orig_re = re in ++ let orig_zeta_i = zeta_i in ++ [@ inline_let] ++ let inv = fun (acc:t_PolynomialRingElement_b (2*b) & usize) (i:usize) -> ++ let (re,zeta_i) = acc in ++ v zeta_i == v orig_zeta_i - v i /\ ++ (forall k. (v k >= 2 * v i * v step (* + 2 * v step *)) ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]) ++ in ++ let re, zeta_i: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) & usize) = ++ Rust_primitives.Iterators.foldi_range #_ #(t_PolynomialRingElement_b (2*b) & usize) #inv { + Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = sz 128 >>! layer <: usize ++ Core.Ops.Range.f_end = sz 128 /! step + } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- (re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) ++ (cast_poly_b #b #(2*b) re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) & usize)) + (fun temp_0_ round -> +- let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize) = temp_0_ in ++ let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) & usize) = temp_0_ in + let round:usize = round in ++ let orig_re_round = re in + let zeta_i:usize = zeta_i -! sz 1 in +- let offset:usize = (round *! step <: usize) *! sz 2 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ assert(v round * v step < 128); ++ assert(v round * v step + v step <= 128); ++ assert(v round * v step * 2 <= 254); ++ assert(v round * v step * 2 + 2 * v step <= 256); ++ let offset:usize = (round *! step) *! sz 2 in ++ assert (v offset + 2 * v step <= 256); ++ assert (v offset + v step <= 256); ++ assert (forall k. v k >= v offset ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]); ++ [@ inline_let] ++ let inv = fun (acc:t_PolynomialRingElement_b (2 * b)) (i:usize) -> ++ (forall k. (v k >= v i /\ v k < v offset + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) /\ ++ (forall k. (v k >= v i + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) ++ in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) = ++ Rust_primitives.Iterators.foldi_range #_ #_ #inv { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! step <: usize +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) ++ } + re + (fun re j -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) = re in ++ assert (re.f_coefficients.[j] == orig_re_round.f_coefficients.[j]); ++ assert (re.f_coefficients.[j +! step] == orig_re_round.f_coefficients.[j +! step]); ++ assert (re.f_coefficients.[j] == orig_re.f_coefficients.[j]); ++ assert (re.f_coefficients.[j +! step] == orig_re.f_coefficients.[j +! step]); ++ let re_j:i32_b b = orig_re.f_coefficients.[j] in ++ let re_j_step:i32_b b = orig_re.f_coefficients.[j +! step] in + let j:usize = j in +- let a_minus_b:i32 = +- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! step <: usize ] <: i32) -! +- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +- in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let a_minus_b:i32_b (2*b) = sub_i32_b re_j_step re_j in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -58,17 +132,13 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + j +- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +! +- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! step <: usize ] +- <: +- i32) +- <: +- i32) ++ (add_i32_b re_j re_j_step) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2 * b) + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let red = mul_zeta_red #v_K #b orig_zeta_i layer a_minus_b round in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -76,67 +146,69 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + (j +! step <: usize) +- (Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (a_minus_b *! +- (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) +- <: +- i32) +- <: +- i32) ++ red + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) + in + re) + in +- re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) ++ re, zeta_i <: t_PolynomialRingElement_b (2*b) & usize) + in +- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b) = re in ++ lemma_zeta_decr orig_zeta_i zeta_i layer; ++ zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) ++#pop-options --let deserialize_then_decompress_10_ (serialized: t_Slice u8) = -+#push-options "--z3rlimit 160" -+let deserialize_then_decompress_10_ serialized = +-let invert_ntt_montgomery (v_K: usize) (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++#push-options "--z3rlimit 500" ++let invert_ntt_montgomery v_K re = let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let b = v v_K * 3328 in ++ assert (v v_K <= 4); ++ assert (b <= 4 * 3328); + let zeta_i:usize = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT /! sz 2 in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 1) ++ assert (v zeta_i == pow2 (8 - 1)); ++ let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) = ++ invert_ntt_at_layer #v_K #b zeta_i re (sz 1) + in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 2) ++ let hoist1 = out in ++ let re = hoist1 in ++ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (4*b)) = ++ invert_ntt_at_layer #v_K zeta_i re (sz 2) + in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 3) ++ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*b)) = ++ invert_ntt_at_layer #v_K zeta_i re (sz 3) + in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 4) ++ assert (8*b = v v_K * 3328 * pow2 (4 - 1)); ++ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (16*b)) = ++ invert_ntt_at_layer #v_K zeta_i re (sz 4) + in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 5) ++ assert (16*b == v v_K * 3328 * pow2 (5 - 1)); ++ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (32*b)) = ++ invert_ntt_at_layer #v_K zeta_i re (sz 5) + in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 6) ++ assert (32*b = v v_K * 3328 * pow2 (6 - 1)); ++ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*b)) = ++ invert_ntt_at_layer #v_K zeta_i re (sz 6) + in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- invert_ntt_at_layer zeta_i re (sz 7) ++ assert (64*b = v v_K * 3328 * pow2 (7 - 1)); ++ let tmp0, re:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (128*b)) = ++ invert_ntt_at_layer #v_K zeta_i re (sz 7) in + let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in + let _:Prims.unit = () <: Prims.unit in + let _:Prims.unit = () <: Prims.unit in - let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact serialized (sz 5) <: Core.Slice.Iter.t_ChunksExact u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ let accT = Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement in -+ let inv (acc: accT) (i: usize) = True in -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv -+ serialized -+ (sz 5) - re - (fun re temp_1_ -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- let i, bytes:(usize & t_Slice u8) = temp_1_ in -- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -- let byte4:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in -- let byte5:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in -- let coefficient1, coefficient2, coefficient3, coefficient4:(i32 & i32 & i32 & i32) = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in -+ let i, bytes:(usize & t_Array u8 (sz 5)) = temp_1_ in -+ let byte1: int_t_d i32_inttype 8 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -+ let byte2: int_t_d i32_inttype 8 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -+ let byte3: int_t_d i32_inttype 8 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -+ let byte4: int_t_d i32_inttype 8 = cast (bytes.[ sz 3 ] <: u8) <: i32 in -+ let byte5: int_t_d i32_inttype 8 = cast (bytes.[ sz 4 ] <: u8) <: i32 in -+ let coefficient1, coefficient2, coefficient3, coefficient4 = - decompress_coefficients_10_ byte2 byte1 byte3 byte4 byte5 - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let coefficient1 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient1 -+ <: -+ i32) in -+ let coefficient2 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient2 -+ <: -+ i32) in -+ let coefficient3 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient3 -+ <: -+ i32) in -+ let coefficient4 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient4 -+ <: -+ i32) in -+ assert_spinoff (v i < 64 ==> 4 * v i + 4 <= 256); -+ assert_spinoff (v i < 64 ==> range (v (sz 4) * v i) usize_inttype); -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -698,14 +801,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (sz 4 *! i <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient1 -- <: -- i32) -+ coefficient1 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -713,14 +814,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 4 *! i <: usize) +! sz 1 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient2 -- <: -- i32) -+ coefficient2 ++ admit(); ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*b) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = sz 2 ++ Core.Ops.Range.f_end = sz 8 } <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -728,14 +827,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 4 *! i <: usize) +! sz 2 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient3 -- <: -- i32) -+ coefficient3 + Core.Ops.Range.t_Range usize) +@@ -144,7 +216,7 @@ + Core.Ops.Range.t_Range usize) + re + (fun re i -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (128*b) = re in + let i:usize = i in + { + re with +@@ -163,52 +235,84 @@ + t_Array i32 (sz 256) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*b)) + in +- re ++ re ++#pop-options + +-let ntt_at_layer +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer v__initial_coefficient_bound: usize) +- = +- let step:usize = sz 1 <= 0 /\ v zeta_i <= 63} ) ++ (layer:usize{v layer > 0 /\ ++ v layer <= 7 /\ ++ v zeta_i == pow2 (7 - v layer) - 1}) ++ (x:i32_b b) ++ (i:usize{v i < 128/(pow2 (v layer))}) ++ : i32_b 3328 ++let mul_zeta_red2 #b zeta_i layer x i = ++ let zeta_i = zeta_i +! sz 1 +! i in ++ let zeta = v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] in ++ assert (b * 1664 < 65536 * 3328); ++ let red = Libcrux.Kem.Kyber.Arithmetic.montgomery_multiply_sfe_by_fer #(3328+b) #1664 x ++ (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) in ++ red ++#pop-options ++ ++#push-options "--ifuel 0 --z3rlimit 5000" ++let ntt_at_layer #b zeta_i re layer initial_coefficient_bound = ++ let step = sz 1 < ++ let (re,zeta_i) = acc in ++ v zeta_i == v orig_zeta_i + v i /\ ++ (forall k. v k >= 2 * v i * v step ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]) ++ in ++ let re, zeta_i: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) & usize) = ++ Rust_primitives.Iterators.foldi_range #_ #(t_PolynomialRingElement_b (3328+b) & usize) #inv { + Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = sz 128 >>! layer <: usize ++ Core.Ops.Range.f_end = loop_end } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) +- (re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) ++ (cast_poly_b #b #(3328+b) re, zeta_i) + (fun temp_0_ round -> +- let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize) = temp_0_ in ++ let re, zeta_i:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) & usize) = temp_0_ in + let round:usize = round in + let zeta_i:usize = zeta_i +! sz 1 in +- let offset:usize = (round *! step <: usize) *! sz 2 in - let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -743,44 +840,43 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 4 *! i <: usize) +! sz 3 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient4 -- <: -- i32) -+ coefficient4 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ assert(v round * v step < 128); ++ assert(v round * v step + v step <= 128); ++ assert(v round * v step * 2 <= 254); ++ assert(v round * v step * 2 + 2 * v step <= 256); ++ let offset:usize = (round *! step) *! sz 2 in ++ assert (v offset + 2 * v step <= 256); ++ assert (v offset + v step <= 256); ++ [@ inline_let] ++ let inv: t_PolynomialRingElement_b (3328+b) -> int_t usize_inttype -> Type0 = ++ fun (acc:t_PolynomialRingElement_b (3328+b)) (i:usize) -> ++ (forall k. (v k >= v i /\ v k < v offset + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) /\ ++ (forall k. (v k >= v i + v step) ==> acc.f_coefficients.[k] == orig_re.f_coefficients.[k]) ++ in ++ assert (forall k. (v k >= v offset /\ v k < v offset + v step) ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]); ++ assert (forall k. (v k >= v offset + v step) ==> re.f_coefficients.[k] == orig_re.f_coefficients.[k]); ++ assert (inv re offset); ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+ b) = ++ Rust_primitives.Iterators.foldi_range #usize_inttype #(t_PolynomialRingElement_b (3328+b)) #inv { + Core.Ops.Range.f_start = offset; + Core.Ops.Range.f_end = offset +! step <: usize +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) ++ } + re + (fun re j -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = re in + let j:usize = j in +- let t:i32 = +- Libcrux.Kem.Kyber.Arithmetic.montgomery_multiply_fe_by_fer (re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! step <: usize ] +- <: +- i32) +- (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) +- in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ assert (re.f_coefficients.[j] == orig_re.f_coefficients.[j]); ++ assert (re.f_coefficients.[j +! step] == orig_re.f_coefficients.[j +! step]); ++ let re_j:i32_b b = orig_re.f_coefficients.[j] in ++ let re_j_step:i32_b b = orig_re.f_coefficients.[j +! step] in ++ let t:i32_b 3328 = mul_zeta_red2 #b orig_zeta_i layer ++ re_j_step round in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -216,12 +320,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + (j +! step <: usize) +- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) -! t <: i32) ++ (sub_i32_b #b #3328 re_j_step t) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -229,64 +333,70 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + j +- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +! t <: i32) ++ (add_i32_b #b #3328 re_j t) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) + in + re) in - re) +- re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement & usize)) ++ re, zeta_i <: (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) & usize)) in - re + let _:Prims.unit = () <: Prims.unit in +- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b) = re in ++ assert (v zeta_i = v orig_zeta_i + 128/v step); ++ assert (v zeta_i = v orig_zeta_i + pow2(7 - v layer)); ++ assert (v zeta_i = pow2(8 - v layer) - 1); ++ zeta_i, hax_temp_output +#pop-options --let deserialize_then_decompress_11_ (serialized: t_Slice u8) = -+#push-options "--z3rlimit 100 --ifuel 0" -+let deserialize_then_decompress_11_ serialized -+ : Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO +-let ntt_at_layer_3_ +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer: usize) +- = +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- ntt_at_layer zeta_i re layer (sz 3) ++let ntt_at_layer_3_ #b zeta_i re layer = ++ let tmp0, out = ++ ntt_at_layer zeta_i re layer (sz 7879) + in + let zeta_i:usize = tmp0 in +- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- +-let ntt_at_layer_3328_ +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer: usize) +- = +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let hax_temp_output = out in ++ zeta_i, hax_temp_output ++ ++let ntt_at_layer_3328_ zeta_i re layer = ++ let tmp0, out = + ntt_at_layer zeta_i re layer (sz 3328) in + let zeta_i:usize = tmp0 in +- let hax_temp_output:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- zeta_i, hax_temp_output <: (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ let hax_temp_output = out in ++ zeta_i, hax_temp_output + +-let ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++#push-options "--ifuel 0 --z3rlimit 1500" ++#restart-solver ++let ntt_binomially_sampled_ring_element re = + let _:Prims.unit = () <: Prims.unit in + let zeta_i:usize = sz 1 in - let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact serialized (sz 11) <: Core.Slice.Iter.t_ChunksExact u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ [@ inline_let] ++ let inv = fun (acc:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207)) (i:usize) -> ++ (v i <= 128) /\ ++ (forall (j:usize). (v j >= v i /\ v j < 128) ==> ++ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207).f_coefficients.[j] 7) /\ ++ (forall (j:usize). (v j >= v i + 128 /\ v j < 256) ==> ++ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207).f_coefficients.[j] 7) ++ in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207 = cast_poly_b re in ++ assert (inv re (sz 0)); ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207 = ++ Rust_primitives.Iterators.foldi_range #_ #(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207) #inv ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = sz 128 + } + <: + Core.Ops.Range.t_Range usize) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #(fun _ _ -> True) -+ serialized -+ (sz 11) - re - (fun re temp_1_ -> +- Core.Ops.Range.t_Range usize) +- re ++ (cast_poly_b re) + (fun re j -> - let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- let i, bytes:(usize & t_Slice u8) = temp_1_ in -- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -- let byte4:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in -- let byte5:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in -- let byte6:i32 = cast (bytes.[ sz 5 ] <: u8) <: i32 in -- let byte7:i32 = cast (bytes.[ sz 6 ] <: u8) <: i32 in -- let byte8:i32 = cast (bytes.[ sz 7 ] <: u8) <: i32 in -- let byte9:i32 = cast (bytes.[ sz 8 ] <: u8) <: i32 in -- let byte10:i32 = cast (bytes.[ sz 9 ] <: u8) <: i32 in -- let byte11:i32 = cast (bytes.[ sz 10 ] <: u8) <: i32 in -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in -+ let i, bytes:(usize & t_Array u8 (sz 11)) = temp_1_ in -+ assert (v i < 32); -+ let byte1: int_t_d i32_inttype 8 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -+ let byte2: int_t_d i32_inttype 8 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -+ let byte3: int_t_d i32_inttype 8 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -+ let byte4: int_t_d i32_inttype 8 = cast (bytes.[ sz 3 ] <: u8) <: i32 in -+ let byte5: int_t_d i32_inttype 8 = cast (bytes.[ sz 4 ] <: u8) <: i32 in -+ let byte6: int_t_d i32_inttype 8 = cast (bytes.[ sz 5 ] <: u8) <: i32 in -+ let byte7: int_t_d i32_inttype 8 = cast (bytes.[ sz 6 ] <: u8) <: i32 in -+ let byte8: int_t_d i32_inttype 8 = cast (bytes.[ sz 7 ] <: u8) <: i32 in -+ let byte9: int_t_d i32_inttype 8 = cast (bytes.[ sz 8 ] <: u8) <: i32 in -+ let byte10: int_t_d i32_inttype 8 = cast (bytes.[ sz 9 ] <: u8) <: i32 in -+ let byte11: int_t_d i32_inttype 8 = cast (bytes.[ sz 10 ] <: u8) <: i32 in - let - coefficient1, - coefficient2, -@@ -789,11 +885,21 @@ - coefficient5, - coefficient6, - coefficient7, -- coefficient8:(i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) = -+ coefficient8 = - decompress_coefficients_11_ byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 - byte11 ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 11207 = cast_poly_b re in + let j:usize = j in +- let t:i32 = +- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! sz 128 <: usize ] <: i32) *! +- (-1600l) ++ let t:i32_b (7*1600) = ++ mul_i32_b (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j +! sz 128 <: usize ]) ++ (-1600l <: i32_b 1600) in - let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let coefficient1 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient1 in -+ let coefficient2 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient2 in -+ let coefficient3 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient3 in -+ let coefficient4 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient4 in -+ let coefficient5 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient5 in -+ let coefficient6 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient6 in -+ let coefficient7 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient7 in -+ let coefficient8 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient8 in -+ assert_spinoff (8 * v i + 8 <= 256); -+ assert_spinoff (range (v (sz 8) * v i) usize_inttype); -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (11207) = { re with Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -801,14 +907,12 @@ +@@ -294,12 +404,10 @@ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (sz 8 *! i <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient1 -- <: -- i32) -+ coefficient1 + (j +! sz 128 <: usize) +- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) -! t <: i32) ++ (sub_i32_b #7 #11200 (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32_b 7) t) } - <: +- <: - Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement in - let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (11207) = { re with Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -816,14 +920,12 @@ +@@ -307,84 +415,76 @@ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 1 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient2 -- <: -- i32) -+ coefficient2 + j +- ((re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ] <: i32) +! t <: i32) ++ (add_i32_b (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ j ]) t) } - <: +- <: - Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + re) + in + let _:Prims.unit = () <: Prims.unit in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ assert (v zeta_i = pow2 (7 - 6) - 1); ++ let zeta_i, re = + ntt_at_layer_3_ zeta_i re (sz 6) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3_ zeta_i re (sz 5) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3_ zeta_i re (sz 4) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3_ zeta_i re (sz 3) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3_ zeta_i re (sz 2) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3_ zeta_i re (sz 1) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207) = re in ++ [@ inline_let] ++ let inv = fun (acc:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207))) (i:usize) -> ++ (v i <= 256) /\ ++ (forall (j:usize). (v j < v i) ==> ++ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207)).f_coefficients.[j] 3328) ++ in ++ assert (inv re (sz 0)); ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207) = ++ Rust_primitives.Iterators.foldi_range #_ #(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207)) #inv ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT + } + <: + Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) + re + (fun re i -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (6*3328+11207) = re in ++ let rei:i32_b (v v_BARRETT_R) = cast_i32_b #(6*3328+11207) #(v v_BARRETT_R) (re ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ]) in ++ let rei: i32_b (6*3328+11207) = cast_i32_b #3328 #(6*3328+11207) ( ++ Libcrux.Kem.Kyber.Arithmetic.barrett_reduce rei) in + let i:usize = i in ++ let re_coeffs:t_Array (i32_b (6*3328+11207)) (sz 256) = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ i rei in + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- i +- (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) +- <: +- i32) +- <: +- t_Array i32 (sz 256) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ = re_coeffs ++ }) + in +- re ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = down_cast_poly_b #(6*3328+11207) #3328 re in ++ re ++#pop-options ++ + +-let ntt_multiply (lhs rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++#push-options "--z3rlimit 100" ++let ntt_multiply lhs rhs = + let _:Prims.unit = () <: Prims.unit in +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 1 = + Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end +@@ -395,34 +495,31 @@ + Core.Ops.Range.t_Range usize) + <: + Core.Ops.Range.t_Range usize) +- out ++ (cast_poly_b out) + (fun out i -> +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = out in + let i:usize = i in +- let product:(i32 & i32) = ++ assert (v i * 4 + 4 <= 256); ++ let product = + ntt_multiply_binomials ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ sz 4 *! i + <: + usize ] + <: +- i32), ++ i32_b 3328), + (lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 1 + <: + usize ] + <: +- i32) +- <: +- (i32 & i32)) +- ((rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ sz 4 *! i <: usize ] <: i32), ++ i32_b 3328)) ++ ((rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ sz 4 *! i <: usize ] <: i32_b 3328), + (rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 1 + <: + usize ] + <: +- i32) +- <: +- (i32 & i32)) +- (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ] <: i32) ++ i32_b 3328)) ++ (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ] <: i32_b 1664) + in +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = { - re with + out with Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -831,14 +933,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 2 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient3 -- <: -- i32) -+ coefficient3 +@@ -433,9 +530,9 @@ + product._1 } <: - Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = { - re with + out with Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -846,14 +946,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 3 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient4 +@@ -446,41 +543,29 @@ + product._2 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 + in +- let product:(i32 & i32) = ++ let product = + ntt_multiply_binomials ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i + <: + usize) +! + sz 2 + <: +- usize ] +- <: +- i32), ++ usize ]), + (lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 3 + <: +- usize ] +- <: +- i32) +- <: +- (i32 & i32)) ++ usize ])) ++ + ((rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 2 + <: +- usize ] +- <: +- i32), ++ usize ]), + (rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 4 *! i <: usize) +! sz 3 + <: +- usize ] - <: - i32) -+ coefficient4 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement +- <: +- (i32 & i32)) +- (Core.Ops.Arith.Neg.neg (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ] <: i32) +- <: +- i32) ++ usize ])) ++ (Core.Ops.Arith.Neg.neg (v_ZETAS_TIMES_MONTGOMERY_R.[ sz 64 +! i <: usize ]) <: i32_b 1664) ++ in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = { - re with + out with Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -861,14 +959,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 4 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient5 -- <: -- i32) -+ coefficient5 +@@ -491,9 +576,9 @@ + product._1 } <: - Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = +- let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let out:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 = { - re with + out with Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -876,14 +972,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 5 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient6 -- <: -- i32) -+ coefficient6 +@@ -504,65 +589,55 @@ + product._2 } <: - Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -891,14 +985,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 6 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient7 -- <: -- i32) -+ coefficient7 + out) + in + out ++#pop-options + +-let ntt_vector_u +- (v_VECTOR_U_COMPRESSION_FACTOR: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- = ++#push-options "--ifuel 0 --z3rlimit 200" ++let ntt_vector_u v_VECTOR_U_COMPRESSION_FACTOR re = + let _:Prims.unit = () <: Prims.unit in + let zeta_i:usize = sz 0 in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 7) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 6) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 5) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 4) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 3) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 2) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let tmp0, out:(usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++ let zeta_i, re = + ntt_at_layer_3328_ zeta_i re (sz 1) + in +- let zeta_i:usize = tmp0 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = out in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ ++ [@ inline_let] ++ let inv = fun (acc:(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328))) (i:usize) -> ++ (v i <= 256) /\ ++ (forall (j:usize). (v j < v i) ==> ++ i32_range (acc <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328)).f_coefficients.[j] 3328) ++ in ++ assert (inv re (sz 0)); ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328) = ++ Rust_primitives.Iterators.foldi_range #_ #(Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328)) #inv ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT } <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -906,35 +998,33 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 7 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient8 + Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) + re + (fun re i -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328) = re in + let i:usize = i in + { + re with +@@ -572,15 +647,10 @@ + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + i + (Libcrux.Kem.Kyber.Arithmetic.barrett_reduce (re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) +- <: +- i32) +- <: +- t_Array i32 (sz 256) ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ])) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (8*3328)) + in +- re ++ down_cast_poly_b #(8*3328) #3328 re ++#pop-options +diff -ruN extraction/Libcrux.Kem.Kyber.Ntt.fsti extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti +--- extraction/Libcrux.Kem.Kyber.Ntt.fsti 2024-05-14 15:56:45.377357286 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti 2024-05-14 15:56:45.461355908 +0200 +@@ -2,276 +2,80 @@ + #set-options "--fuel 0 --ifuel 1 --z3rlimit 15" + open Core + open FStar.Mul ++open Libcrux.Kem.Kyber.Arithmetic + +-let v_ZETAS_TIMES_MONTGOMERY_R: t_Array i32 (sz 128) = +- let list = +- [ +- (-1044l); (-758l); (-359l); (-1517l); 1493l; 1422l; 287l; 202l; (-171l); 622l; 1577l; 182l; +- 962l; (-1202l); (-1474l); 1468l; 573l; (-1325l); 264l; 383l; (-829l); 1458l; (-1602l); (-130l); +- (-681l); 1017l; 732l; 608l; (-1542l); 411l; (-205l); (-1571l); 1223l; 652l; (-552l); 1015l; +- (-1293l); 1491l; (-282l); (-1544l); 516l; (-8l); (-320l); (-666l); (-1618l); (-1162l); 126l; +- 1469l; (-853l); (-90l); (-271l); 830l; 107l; (-1421l); (-247l); (-951l); (-398l); 961l; +- (-1508l); (-725l); 448l; (-1065l); 677l; (-1275l); (-1103l); 430l; 555l; 843l; (-1251l); 871l; +- 1550l; 105l; 422l; 587l; 177l; (-235l); (-291l); (-460l); 1574l; 1653l; (-246l); 778l; 1159l; +- (-147l); (-777l); 1483l; (-602l); 1119l; (-1590l); 644l; (-872l); 349l; 418l; 329l; (-156l); +- (-75l); 817l; 1097l; 603l; 610l; 1322l; (-1285l); (-1465l); 384l; (-1215l); (-136l); 1218l; +- (-1335l); (-874l); 220l; (-1187l); (-1659l); (-1185l); (-1530l); (-1278l); 794l; (-1510l); +- (-854l); (-870l); 478l; (-108l); (-308l); 996l; 991l; 958l; (-1460l); 1522l; 1628l +- ] +- in +- FStar.Pervasives.assert_norm (Prims.eq2 (List.Tot.length list) 128); +- Rust_primitives.Hax.array_of_list 128 list ++val v_ZETAS_TIMES_MONTGOMERY_R: x:t_Array (i32_b 1664) (sz 128){v (x.[sz 1] <: i32) == -758} + +-/// Compute the product of two Kyber binomials with respect to the +-/// modulus `X² - zeta`. +-/// This function almost implements Algorithm 11 of the +-/// NIST FIPS 203 standard, which is reproduced below: +-/// ```plaintext +-/// Input: a₀, a₁, b₀, b₁ ∈ ℤq. +-/// Input: γ ∈ ℤq. +-/// Output: c₀, c₁ ∈ ℤq. +-/// c₀ ← a₀·b₀ + a₁·b₁·γ +-/// c₁ ← a₀·b₁ + a₁·b₀ +-/// return c₀, c₁ +-/// ``` +-/// We say "almost" because the coefficients output by this function are in +-/// the Montgomery domain (unlike in the specification). +-/// The NIST FIPS 203 standard can be found at +-/// . +-val ntt_multiply_binomials: (i32 & i32) -> (i32 & i32) -> zeta: i32 +- -> Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) +- +-val invert_ntt_at_layer +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer: usize) +- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// Use the Gentleman-Sande butterfly to invert, in-place, the NTT representation +-/// of a `KyberPolynomialRingElement`. The coefficients of the output +-/// ring element are in the Montgomery domain. +-val invert_ntt_montgomery (v_K: usize) (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// Represents an intermediate polynomial splitting step in the NTT. All +-/// resulting coefficients are in the normal domain since the zetas have been +-/// multiplied by MONTGOMERY_R. +-val ntt_at_layer +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer v__initial_coefficient_bound: usize) +- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++val ntt_multiply_binomials (a:wfFieldElement&wfFieldElement) (b: wfFieldElement&wfFieldElement) (zeta: i32_b 1664) : ++ Pure (wfFieldElement & wfFieldElement) ++ (requires True) ++ (ensures (fun _ -> True)) ++ ++val invert_ntt_at_layer (#v_K:usize{v v_K >= 1 /\ v v_K <= 4}) ++ (#b:nat{b <= v v_K * 3328 * 64}) ++ (zeta_i: usize{v zeta_i >= 1 /\ v zeta_i <= 128}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) ++ (layer: usize{v layer > 0 /\ ++ v layer <= 7 /\ ++ v zeta_i == pow2 (8 - v layer) /\ ++ b == v v_K * 3328 * pow2(v layer - 1)}) ++ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) + Prims.l_True +- (fun _ -> Prims.l_True) ++ (fun x -> let (zeta_fin,re) = x in v zeta_fin == pow2 (7 - v layer)) + +-/// See [`ntt_at_layer`]. +-val ntt_at_layer_3_ +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer: usize) +- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++val invert_ntt_montgomery (v_K: usize{v v_K >= 1 /\ v v_K <= 4}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) ++ : Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) ++ ++val ntt_at_layer ++ (#b:nat{b <= 31175}) ++ (zeta_i: usize{v zeta_i < 128}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) ++ (layer: usize{v layer > 0 /\ ++ v layer <= 7 /\ ++ v zeta_i == pow2 (7 - v layer) - 1}) ++ (initial_coefficient_bound: usize{b == (7 - v layer) * 3328 + v initial_coefficient_bound}) ++ : Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) ++ (requires True) ++ (ensures fun (zeta_i, result) -> v zeta_i == pow2 (8 - v layer) - 1) ++ ++val ntt_at_layer_3_ (#b:nat) ++ (zeta_i: usize{v zeta_i < 128}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) ++ (layer: usize{v layer > 0 /\ ++ v layer <= 6 /\ ++ v zeta_i == pow2 (7 - v layer) - 1 /\ ++ b == (6 - v layer) * 3328 + 11207}) ++ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) + Prims.l_True +- (fun _ -> Prims.l_True) ++ (ensures fun (zeta_i,result) -> v zeta_i == pow2 (8 - v layer) - 1) + +-/// See [`ntt_at_layer`]. +-val ntt_at_layer_3328_ +- (zeta_i: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- (layer: usize) +- : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++val ntt_at_layer_3328_ (#b:nat{b <= 7*3328}) ++ (zeta_i: usize{v zeta_i < 128}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) ++ (layer: usize{v layer > 0 /\ ++ v layer <= 7 /\ ++ v zeta_i == pow2 (7 - v layer) - 1 /\ ++ b == (7 - v layer) * 3328 + 3328}) ++ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) + Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// Use the Cooley–Tukey butterfly to compute an in-place NTT representation +-/// of a `KyberPolynomialRingElement`. +-/// This function operates only on those which were produced by binomial +-/// sampling, and thus those which have small coefficients. The small +-/// coefficients let us skip the first round of Montgomery reductions. +-val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- (requires +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) - <: -- i32) -+ coefficient8 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in - re) - in - re -+#pop-options +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) +- <: +- i32) <=. +- 3l +- <: +- bool) +- <: +- bool)) +- (ensures +- fun result -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ +- i ] +- <: +- i32) +- <: +- i32) <. +- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- bool) +- <: +- bool)) ++ (ensures fun (zeta_i,result) -> v zeta_i == pow2 (8 - v layer) - 1) --let deserialize_then_decompress_4_ (serialized: t_Slice u8) = -+#push-options "--z3rlimit 100" -+let deserialize_then_decompress_4_ serialized = - let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__iter serialized <: Core.Slice.Iter.t_Iter u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter u8)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter u8)) -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Rust_primitives.Iterators.foldi_slice #_ #_ #(fun _ _ -> True) -+ serialized - re - (fun re temp_1_ -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in - let i, byte:(usize & u8) = temp_1_ in -- let coefficient1, coefficient2:(i32 & i32) = decompress_coefficients_4_ byte in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let coefficient1, coefficient2 = decompress_coefficients_4_ byte in -+ assert_spinoff (v i < 128 ==> 2 * v i + 1 < 256); -+ assert_spinoff (v i < 128 ==> range (v (sz 2) * v i) usize_inttype); -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -947,9 +1037,9 @@ - i32) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -962,33 +1052,32 @@ - i32) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in - re) - in - re -+#pop-options +-/// Given two `KyberPolynomialRingElement`s in their NTT representations, +-/// compute their product. Given two polynomials in the NTT domain `f^` and `ĵ`, +-/// the `iᵗʰ` coefficient of the product `k\u{302}` is determined by the calculation: +-/// ```plaintext +-/// ĥ[2·i] + ĥ[2·i + 1]X = (f^[2·i] + f^[2·i + 1]X)·(ĝ[2·i] + ĝ[2·i + 1]X) mod (X² - ζ^(2·BitRev₇(i) + 1)) +-/// ``` +-/// This function almost implements Algorithm 10 of the +-/// NIST FIPS 203 standard, which is reproduced below: +-/// ```plaintext +-/// Input: Two arrays fˆ ∈ ℤ₂₅₆ and ĝ ∈ ℤ₂₅₆. +-/// Output: An array ĥ ∈ ℤq. +-/// for(i ← 0; i < 128; i++) +-/// (ĥ[2i], ĥ[2i+1]) ← BaseCaseMultiply(fˆ[2i], fˆ[2i+1], ĝ[2i], ĝ[2i+1], ζ^(2·BitRev₇(i) + 1)) +-/// end for +-/// return ĥ +-/// ``` +-/// We say \"almost\" because the coefficients of the ring element output by +-/// this function are in the Montgomery domain. +-/// The NIST FIPS 203 standard can be found at +-/// . +-val ntt_multiply (lhs rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- (requires +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] <: i32) >=. 0l <: bool) && +- ((lhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] <: i32) <. 4096l <: bool +- ) && +- ((Core.Num.impl__i32__abs (rhs.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) +- <: +- i32) <=. +- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- bool)) +- <: +- bool)) +- (ensures +- fun result -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ +- i ] +- <: +- i32) +- <: +- i32) <=. +- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- bool) +- <: +- bool)) +- +-/// Use the Cooley–Tukey butterfly to compute an in-place NTT representation +-/// of a `KyberPolynomialRingElement`. +-/// This function operates on the ring element that partly constitutes +-/// the ciphertext. ++val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7) ++ : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires True) ++ (ensures (fun _ -> True)) ++ ++val ntt_multiply (lhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) ++ (rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) ++ : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) ++ (requires True) ++ (ensures (fun _ -> True)) ++ + val ntt_vector_u + (v_VECTOR_U_COMPRESSION_FACTOR: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- (requires +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ i ] +- <: +- i32) +- <: +- i32) <=. +- 3328l +- <: +- bool) +- <: +- bool)) +- (ensures +- fun result -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ +- i ] +- <: +- i32) +- <: +- i32) <. +- Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS +- <: +- bool) +- <: +- bool)) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) ++ : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires True) ++ (ensures fun _ -> True) ++ +diff -ruN extraction/Libcrux.Kem.Kyber.Sampling.fst extraction-edited/Libcrux.Kem.Kyber.Sampling.fst +--- extraction/Libcrux.Kem.Kyber.Sampling.fst 2024-05-14 15:56:45.383357188 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Sampling.fst 2024-05-14 15:56:45.466355826 +0200 +@@ -3,22 +3,34 @@ + open Core + open FStar.Mul --let deserialize_then_decompress_5_ (serialized: t_Slice u8) = -+#push-options "--z3rlimit 150" -+let deserialize_then_decompress_5_ serialized = - let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++let rejection_sampling_panic_with_diagnostic () : Prims.unit = ++ admit(); // This should never be reachable ++ Rust_primitives.Hax.never_to_any (Core.Panicking.panic "explicit panic" ++ <: ++ Rust_primitives.Hax.t_Never) ++ ++#push-options "--ifuel 0 --z3rlimit 100" + let sample_from_binomial_distribution_2_ (randomness: t_Slice u8) = +- let (sampled: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement):Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- = - Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let sampled: t_PolynomialRingElement_b 3 = ++ cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact serialized (sz 5) <: Core.Slice.Iter.t_ChunksExact u8) +- (Core.Slice.impl__chunks_exact randomness (sz 4) <: Core.Slice.Iter.t_ChunksExact u8) - <: - Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) - <: - Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #(fun _ _ -> True) -+ serialized (sz 5) - re - (fun re temp_1_ -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- let i, bytes:(usize & t_Slice u8) = temp_1_ in -- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -- let byte4:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in -- let byte5:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in -+ let i, bytes:(usize & t_Array u8 (sz 5)) = temp_1_ in -+ assert (v i < 32); -+ let byte1 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -+ let byte2 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -+ let byte3 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -+ let byte4 = cast (bytes.[ sz 3 ] <: u8) <: i32 in -+ let byte5 = cast (bytes.[ sz 4 ] <: u8) <: i32 in - let - coefficient1, - coefficient2, -@@ -997,10 +1086,25 @@ - coefficient5, - coefficient6, - coefficient7, -- coefficient8:(i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) = -+ coefficient8 = - decompress_coefficients_5_ byte1 byte2 byte3 byte4 byte5 - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let coefficient1 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient1 in -+ let coefficient2 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient2 in -+ let coefficient3 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient3 in -+ let coefficient4 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient4 in -+ let coefficient5 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient5 in -+ let coefficient6 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient6 in -+ let coefficient7 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient7 in -+ let coefficient8 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient8 in -+ // assert (Seq.length serialized == 160); -+ // // assert_norm (160 / 5 == 32); -+ // assert_spinoff (v i < Seq.length serialized); -+ // assert (v i < 32); -+ assert_spinoff (v i < 32 ==> 8 * v i + 8 <= 256); -+ mul_in_range 8 (v i); -+ assert_spinoff (v i < 32 ==> range (v (sz 8) * v i) usize_inttype); -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1008,14 +1112,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (sz 8 *! i <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient1 -- <: -- i32) -+ coefficient1 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1023,14 +1125,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 1 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient2 -- <: -- i32) -+ coefficient2 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1038,14 +1138,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 2 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient3 -- <: -- i32) -+ coefficient3 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1053,14 +1151,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 3 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient4 -- <: -- i32) -+ coefficient4 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1068,14 +1164,12 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 4 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient5 -- <: -- i32) -+ coefficient5 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ ++ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> True in ++ let sl : t_Slice u8 = randomness in ++ let chunk_len = sz 4 in ++ assert (v (length sl) == 128); ++ assert (Seq.length sl == 128); ++ assert_norm (128 % 4 == 0); ++ let sampled = ++ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv ++ sl ++ chunk_len + sampled + (fun sampled temp_1_ -> +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in +- let chunk_number, byte_chunk:(usize & t_Slice u8) = temp_1_ in ++ let chunk_number, byte_chunk:(usize & t_Array u8 chunk_len) = temp_1_ in ++ assert(chunk_number <. sz 32); + let (random_bits_as_u32: u32):u32 = + (((cast (byte_chunk.[ sz 0 ] <: u8) <: u32) |. + ((cast (byte_chunk.[ sz 1 ] <: u8) <: u32) <>! 1l <: u32) &. 1431655765ul in ++ logand_lemma (random_bits_as_u32 >>! 1l <: u32) 1431655765ul; ++ assert(odd_bits <=. 1431655765ul); + let coin_toss_outcomes:u32 = even_bits +! odd_bits in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_step_by +- ({ ++ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 in ++ [@ inline_let] ++ let inv : acc_t -> u32 -> Type = fun acc i -> True in ++ Rust_primitives.Iterators.foldi_range_step_by #u32_inttype #(acc_t) #inv ({ + Core.Ops.Range.f_start = 0ul; + Core.Ops.Range.f_end = Core.Num.impl__u32__BITS +- } +- <: +- Core.Ops.Range.t_Range u32) +- (sz 4) - <: -- i32) -+ coefficient6 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement +- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range u32)) +- <: +- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range u32)) ++ } ++ <: ++ Core.Ops.Range.t_Range u32) ++ (sz 4) + sampled + (fun sampled outcome_set -> +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in + let outcome_set:u32 = outcome_set in ++ assert (v outcome_set + 4 <= 32); ++ let out_1 = ((coin_toss_outcomes >>! outcome_set <: u32) &. 3ul <: u32) in + let outcome_1_:i32 = +- cast ((coin_toss_outcomes >>! outcome_set <: u32) &. 3ul <: u32) <: i32 ++ cast out_1 <: i32 + in ++ let out_2 = ((coin_toss_outcomes >>! (outcome_set +! 2ul <: u32) <: u32) &. 3ul <: u32) in + let outcome_2_:i32 = +- cast ((coin_toss_outcomes >>! (outcome_set +! 2ul <: u32) <: u32) &. 3ul <: u32) +- <: +- i32 ++ cast out_2 <: i32 + in ++ logand_lemma (coin_toss_outcomes >>! outcome_set <: u32) 3ul; ++ assert (v out_1 >= 0); ++ assert (v out_1 <= 3); ++ assert (v outcome_1_ == v out_1 @% pow2 32); ++ Math.Lemmas.small_modulo_lemma_1 (v out_1) (pow2 32); ++ assert (v outcome_1_ == v out_1); ++ assert (v outcome_1_ >= 0 /\ v outcome_1_ <= 3); ++ logand_lemma (coin_toss_outcomes >>! (outcome_set +! 2ul <: u32) <: u32) 3ul; ++ assert (v out_2 >= 0); ++ assert (v out_2 <= 3); ++ assert (v outcome_2_ == v out_2 @% pow2 32); ++ Math.Lemmas.small_modulo_lemma_1 (v out_2) (pow2 32); ++ assert (v outcome_2_ == v out_2); ++ assert (v outcome_2_ >= 0 /\ v outcome_2_ <= 3); + let offset:usize = cast (outcome_set >>! 2l <: u32) <: usize in +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ assert (outcome_set <. 32ul); ++ assert (v (outcome_set >>! 2l <: u32) = v outcome_set / 4); ++ assert (v (outcome_set >>! 2l <: u32) < 8); ++ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set >>! 2l <: u32)) (pow2 32); ++ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set >>! 2l <: u32)) (pow2 64); ++ assert (v offset < 8); ++ assert (8 * v chunk_number + 8 <= 256); ++ assert (8 * v chunk_number + v offset < 256); ++ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 = + { + sampled with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -68,29 +104,36 @@ + (outcome_1_ -! outcome_2_ <: i32) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3 + in + sampled)) +- in +- let _:Prims.unit = () <: Prims.unit in +- sampled ++ in ++ let _:Prims.unit = () <: Prims.unit in ++ admit(); // P-F ++ sampled ++#pop-options + ++#push-options "--ifuel 0 --z3rlimit 200" + let sample_from_binomial_distribution_3_ (randomness: t_Slice u8) = +- let (sampled: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement):Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let sampled:t_PolynomialRingElement_b 7 = ++ (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) + in +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact randomness (sz 3) <: Core.Slice.Iter.t_ChunksExact u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) (i:usize) -> True in ++ let sl : t_Slice u8 = randomness in ++ let chunk_len = sz 3 in ++ assert (v (length sl) == 192); ++ assert (Seq.length sl == 192); ++ assert_norm (192 % 3 == 0); ++ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = ++ Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv ++ sl ++ chunk_len + sampled + (fun sampled temp_1_ -> +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in +- let chunk_number, byte_chunk:(usize & t_Slice u8) = temp_1_ in ++ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = sampled in ++ let chunk_number, byte_chunk:(usize & t_Array u8 chunk_len) = temp_1_ in + let (random_bits_as_u24: u32):u32 = + ((cast (byte_chunk.[ sz 0 ] <: u8) <: u32) |. + ((cast (byte_chunk.[ sz 1 ] <: u8) <: u32) <>! 1l <: u32) &. 2396745ul in ++ logand_lemma (random_bits_as_u24 >>! 1l <: u32) 2396745ul; ++ assert (second_bits <=. 2396745ul); + let third_bits:u32 = (random_bits_as_u24 >>! 2l <: u32) &. 2396745ul in ++ logand_lemma (random_bits_as_u24 >>! 2l <: u32) 2396745ul; ++ assert (third_bits <=. 2396745ul); + let coin_toss_outcomes:u32 = (first_bits +! second_bits <: u32) +! third_bits in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_step_by +- ({ Core.Ops.Range.f_start = 0l; Core.Ops.Range.f_end = 24l } +- <: +- Core.Ops.Range.t_Range i32) +- (sz 6) - <: -- i32) -+ coefficient7 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement +- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range i32)) +- <: +- Core.Iter.Adapters.Step_by.t_StepBy (Core.Ops.Range.t_Range i32)) ++ let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 in ++ [@ inline_let] ++ let inv : acc_t -> i32 -> Type = fun acc i -> True in ++ Rust_primitives.Iterators.foldi_range_step_by #i32_inttype #(acc_t) #inv ({ ++ Core.Ops.Range.f_start = 0l; ++ Core.Ops.Range.f_end = 24l ++ } ++ <: ++ Core.Ops.Range.t_Range i32) ++ (sz 6) + sampled + (fun sampled outcome_set -> +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = sampled in ++ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = sampled in + let outcome_set:i32 = outcome_set in + let outcome_1_:i32 = + cast ((coin_toss_outcomes >>! outcome_set <: u32) &. 7ul <: u32) <: i32 +@@ -123,8 +173,22 @@ + <: + i32 + in ++ logand_lemma (coin_toss_outcomes >>! outcome_set <: u32) 7ul; ++ Math.Lemmas.small_modulo_lemma_1 (v ((coin_toss_outcomes >>! outcome_set <: u32) &. 7ul <: u32)) (pow2 32); ++ assert (v outcome_1_ >= 0 /\ v outcome_1_ <= 7); ++ logand_lemma (coin_toss_outcomes >>! (outcome_set +! 3l <: i32) <: u32) 7ul; ++ Math.Lemmas.small_modulo_lemma_1 (v ((coin_toss_outcomes >>! (outcome_set +! 3l <: i32) <: u32) &. 7ul <: u32)) (pow2 32); ++ assert (v outcome_2_ >= 0 /\ v outcome_2_ <= 7); + let offset:usize = cast (outcome_set /! 6l <: i32) <: usize in +- let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ assert (outcome_set <. 24l); ++ assert (v (outcome_set /! 6l <: i32) = v outcome_set / 6); ++ assert (v (outcome_set /! 6l <: i32) < 4); ++ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set /! 6l <: i32)) (pow2 32); ++ Math.Lemmas.small_modulo_lemma_1 (v (outcome_set /! 6l <: i32)) (pow2 64); ++ assert (v offset < 4); ++ assert (4 * v chunk_number + 4 <= 256); ++ assert (4 * v chunk_number + v offset < 256); ++ let sampled:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 = + { + sampled with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -135,15 +199,18 @@ + (outcome_1_ -! outcome_2_ <: i32) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7 + in + sampled)) + in + let _:Prims.unit = () <: Prims.unit in ++ admit(); + sampled ++#pop-options + + let sample_from_binomial_distribution (v_ETA: usize) (randomness: t_Slice u8) = + let _:Prims.unit = () <: Prims.unit in ++ Rust_primitives.Integers.mk_int_equiv_lemma #u32_inttype (v v_ETA); + match cast (v_ETA <: usize) <: u32 with + | 2ul -> sample_from_binomial_distribution_2_ randomness + | 3ul -> sample_from_binomial_distribution_3_ randomness +@@ -153,226 +220,131 @@ + <: + Rust_primitives.Hax.t_Never) + +-let sample_from_uniform_distribution_next +- (v_K v_N: usize) +- (randomness: t_Array (t_Array u8 v_N) v_K) +- (sampled_coefficients: t_Array usize v_K) +- (out: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- = +- let done:bool = true in +- let done, out, sampled_coefficients:(bool & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ +- Core.Ops.Range.f_start = sz 0; +- Core.Ops.Range.f_end = v_K +- } +- <: +- Core.Ops.Range.t_Range usize) +- <: +- Core.Ops.Range.t_Range usize) ++#push-options "--z3rlimit 50" ++let sample_from_uniform_distribution (randomness: t_Array u8 (sz 840)) = ++ let (sampled_coefficients: usize):usize = sz 0 in ++ let (out: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement):Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ in ++ let done:bool = false in ++ let acc_t = (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) in ++ [@ inline_let] ++ let inv = fun (acc:acc_t) -> True in ++ let sl : t_Slice u8 = randomness in ++ let chunk_len = sz 3 in ++ let done, out, sampled_coefficients:(bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & ++ usize) = ++ Rust_primitives.Iterators.fold_chunks_exact #u8 #acc_t #inv ++ sl ++ chunk_len + (done, out, sampled_coefficients + <: +- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array usize v_K +- )) +- (fun temp_0_ i -> ++ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize)) ++ (fun temp_0_ bytes -> + let done, out, sampled_coefficients:(bool & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) = ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & ++ usize) = + temp_0_ in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1113,33 +1203,27 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - ((sz 8 *! i <: usize) +! sz 7 <: usize) -- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient8 -- <: -- i32) -+ coefficient8 - } +- let i:usize = i in +- let out, sampled_coefficients:(t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Slice.impl__chunks +- (Rust_primitives.unsize (randomness.[ i ] <: t_Array u8 v_N) <: t_Slice u8) +- (sz 3) +- <: +- Core.Slice.Iter.t_Chunks u8) ++ let bytes:t_Array u8 chunk_len = bytes in ++ if ~.done <: bool ++ then ++ let b1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in ++ let b2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in ++ let b3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in ++ assert(v b1 >= 0 /\ v b1 < pow2 8); ++ assert(v b2 >= 0 /\ v b2 < pow2 8); ++ assert(v b3 >= 0 /\ v b3 < pow2 8); ++ let d1:i32 = ((b2 &. 15l <: i32) <= v b1); ++ assert (v d1 >= 0); ++ let d2:i32 = (b3 <>! 4l <: i32) in ++ logor_lemma (b3 <>! 4l <: i32); ++ assert (v d2 >= v b3 * pow2 4); ++ assert (v d2 >= 0); ++ let out, sampled_coefficients:(Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & ++ usize) = ++ if ++ d1 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && ++ sampled_coefficients <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT ++ then ++ let out:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ { ++ out with ++ Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ sampled_coefficients ++ d1 ++ } ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ in ++ out, sampled_coefficients +! sz 1 + <: +- Core.Slice.Iter.t_Chunks u8) +- (out, sampled_coefficients ++ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) ++ else ++ out, sampled_coefficients + <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K)) +- (fun temp_0_ bytes -> +- let out, sampled_coefficients:(t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) = +- temp_0_ +- in +- let bytes:t_Slice u8 = bytes in +- let b1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in +- let b2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in +- let b3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in +- let d1:i32 = ((b2 &. 15l <: i32) <>! 4l <: i32) in +- let out, sampled_coefficients:(t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) = +- if +- d1 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && +- (sampled_coefficients.[ i ] <: usize) <. +- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- then +- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out +- i +- ({ +- (out.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (out.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- (sampled_coefficients.[ i ] <: usize) +- d1 +- <: +- t_Array i32 (sz 256) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- in +- out, +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize sampled_coefficients +- i +- ((sampled_coefficients.[ i ] <: usize) +! sz 1 <: usize) +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) +- else +- out, sampled_coefficients +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) +- in +- if +- d2 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && +- (sampled_coefficients.[ i ] <: usize) <. +- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- then +- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out +- i +- ({ +- (out.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize (out.[ i ] +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- (sampled_coefficients.[ i ] <: usize) +- d2 +- <: +- t_Array i32 (sz 256) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- in +- let sampled_coefficients:t_Array usize v_K = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize sampled_coefficients +- i +- ((sampled_coefficients.[ i ] <: usize) +! sz 1 <: usize) +- in +- out, sampled_coefficients +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) +- else +- out, sampled_coefficients +- <: +- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K)) +- in +- if +- (sampled_coefficients.[ i ] <: usize) <. +- Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT +- then +- false, out, sampled_coefficients +- <: +- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K) ++ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) ++ in ++ let out, sampled_coefficients:(Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & ++ usize) = ++ if ++ d2 <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS && ++ sampled_coefficients <. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT ++ then ++ let out:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ { ++ out with ++ Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ = ++ Rust_primitives.Hax.Monomorphized_update_at.update_at_usize out ++ .Libcrux.Kem.Kyber.Arithmetic.f_coefficients ++ sampled_coefficients ++ d2 ++ } ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ in ++ let sampled_coefficients:usize = sampled_coefficients +! sz 1 in ++ out, sampled_coefficients ++ <: ++ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) ++ else ++ out, sampled_coefficients ++ <: ++ (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) ++ in ++ if sampled_coefficients =. Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT ++ then ++ let done:bool = true in ++ done, out, sampled_coefficients ++ <: ++ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) ++ else ++ done, out, sampled_coefficients ++ <: ++ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize) + else + done, out, sampled_coefficients <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in - re) +- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K)) ++ (bool & Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement & usize)) + in +- let hax_temp_output:bool = done in +- sampled_coefficients, out, hax_temp_output +- <: +- (t_Array usize v_K & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & bool) +- +-let sample_from_xof (v_K: usize) (seeds: t_Array (t_Array u8 (sz 34)) v_K) = +- let (sampled_coefficients: t_Array usize v_K):t_Array usize v_K = +- Rust_primitives.Hax.repeat (sz 0) v_K +- in +- let (out: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K):t_Array +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = +- Libcrux.Kem.Kyber.Hash_functions.absorb v_K seeds +- in +- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & +- t_Array (t_Array u8 (sz 504)) v_K) = +- Libcrux.Kem.Kyber.Hash_functions.squeeze_three_blocks v_K xof_state +- in +- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in +- let randomness:t_Array (t_Array u8 (sz 504)) v_K = out1 in +- let tmp0, tmp1, out1:(t_Array usize v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- bool) = +- sample_from_uniform_distribution_next v_K (sz 504) randomness sampled_coefficients out +- in +- let sampled_coefficients:t_Array usize v_K = tmp0 in +- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = tmp1 in +- let done:bool = out1 in +- let done, out, sampled_coefficients, xof_state:(bool & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K & +- Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = +- Rust_primitives.f_while_loop (fun temp_0_ -> +- let done, out, sampled_coefficients, xof_state:(bool & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K & +- Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = +- temp_0_ +- in +- ~.done <: bool) +- (done, out, sampled_coefficients, xof_state +- <: +- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array usize v_K & +- Libcrux.Digest.Incremental_x4.t_Shake128StateX4)) +- (fun temp_0_ -> +- let done, out, sampled_coefficients, xof_state:(bool & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K & +- Libcrux.Digest.Incremental_x4.t_Shake128StateX4) = +- temp_0_ +- in +- let tmp0, out1:(Libcrux.Digest.Incremental_x4.t_Shake128StateX4 & +- t_Array (t_Array u8 (sz 168)) v_K) = +- Libcrux.Kem.Kyber.Hash_functions.squeeze_block v_K xof_state +- in +- let xof_state:Libcrux.Digest.Incremental_x4.t_Shake128StateX4 = tmp0 in +- let randomness:t_Array (t_Array u8 (sz 168)) v_K = out1 in +- let tmp0, tmp1, out1:(t_Array usize v_K & +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- bool) = +- sample_from_uniform_distribution_next v_K (sz 168) randomness sampled_coefficients out +- in +- let sampled_coefficients:t_Array usize v_K = tmp0 in +- let out:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = tmp1 in +- let done:bool = out1 in +- done, out, sampled_coefficients, xof_state +- <: +- (bool & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & +- t_Array usize v_K & +- Libcrux.Digest.Incremental_x4.t_Shake128StateX4)) ++ let _:Prims.unit = ++ if ~.done ++ then ++ let _:Prims.unit = rejection_sampling_panic_with_diagnostic () in ++ () + in +- let _:Prims.unit = Libcrux.Kem.Kyber.Hash_functions.free_state xof_state in +- out ++ let _:Prims.unit = () <: Prims.unit in ++ out ++#pop-options +diff -ruN extraction/Libcrux.Kem.Kyber.Sampling.fsti extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti +--- extraction/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-14 15:56:45.417356630 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-14 15:56:45.436356318 +0200 +@@ -3,155 +3,37 @@ + open Core + open FStar.Mul + +-/// Given a series of uniformly random bytes in `randomness`, for some number `eta`, +-/// the `sample_from_binomial_distribution_{eta}` functions sample +-/// a ring element from a binomial distribution centered at 0 that uses two sets +-/// of `eta` coin flips. If, for example, +-/// `eta = ETA`, each ring coefficient is a value `v` such +-/// such that `v ∈ {-ETA, -ETA + 1, ..., 0, ..., ETA + 1, ETA}` and: +-/// ```plaintext +-/// - If v < 0, Pr[v] = Pr[-v] +-/// - If v >= 0, Pr[v] = BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2 ^ (2 * ETA) +-/// ``` +-/// The values `v < 0` are mapped to the appropriate `KyberFieldElement`. +-/// The expected value is: +-/// ```plaintext +-/// E[X] = (-ETA)Pr[-ETA] + (-(ETA - 1))Pr[-(ETA - 1)] + ... + (ETA - 1)Pr[ETA - 1] + (ETA)Pr[ETA] +-/// = 0 since Pr[-v] = Pr[v] when v < 0. +-/// ``` +-/// And the variance is: +-/// ```plaintext +-/// Var(X) = E[(X - E[X])^2] +-/// = E[X^2] +-/// = sum_(v=-ETA to ETA)v^2 * (BINOMIAL_COEFFICIENT(2 * ETA; ETA - v) / 2^(2 * ETA)) +-/// = ETA / 2 +-/// ``` +-/// This function implements Algorithm 7 of the NIST FIPS 203 standard, which is +-/// reproduced below: +-/// ```plaintext +-/// Input: byte array B ∈ 𝔹^{64η}. +-/// Output: array f ∈ ℤ₂₅₆. +-/// b ← BytesToBits(B) +-/// for (i ← 0; i < 256; i++) +-/// x ← ∑(j=0 to η - 1) b[2iη + j] +-/// y ← ∑(j=0 to η - 1) b[2iη + η + j] +-/// f[i] ← x−y mod q +-/// end for +-/// return f +-/// ``` +-/// The NIST FIPS 203 standard can be found at +-/// . ++open Libcrux.Kem.Kyber.Arithmetic ++ + val sample_from_binomial_distribution_2_ (randomness: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ : Prims.Pure (t_PolynomialRingElement_b 3) + (requires (Core.Slice.impl__len randomness <: usize) =. (sz 2 *! sz 64 <: usize)) + (ensures + fun result -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ +- i ] +- <: +- i32) +- <: +- i32) <=. +- 2l +- <: +- bool) +- <: +- bool)) ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b result == ++ Spec.Kyber.sample_poly_binomial (sz 2) randomness) + + val sample_from_binomial_distribution_3_ (randomness: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ : Prims.Pure (t_PolynomialRingElement_b 7) + (requires (Core.Slice.impl__len randomness <: usize) =. (sz 3 *! sz 64 <: usize)) + (ensures + fun result -> +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = result in +- Hax_lib.v_forall (fun i -> +- let i:usize = i in +- Hax_lib.implies (i <. +- (Core.Slice.impl__len (Rust_primitives.unsize result +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- <: +- usize) +- <: +- bool) +- (fun temp_0_ -> +- let _:Prims.unit = temp_0_ in +- (Core.Num.impl__i32__abs (result.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ +- i ] +- <: +- i32) +- <: +- i32) <=. +- 3l +- <: +- bool) +- <: +- bool)) +- +-val sample_from_binomial_distribution (v_ETA: usize) (randomness: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b result == ++ Spec.Kyber.sample_poly_binomial (sz 3) randomness) + +-/// If `bytes` contains a set of uniformly random bytes, this function +-/// uniformly samples a ring element `â` that is treated as being the NTT representation +-/// of the corresponding polynomial `a`. +-/// Since rejection sampling is used, it is possible the supplied bytes are +-/// not enough to sample the element, in which case an `Err` is returned and the +-/// caller must try again with a fresh set of bytes. +-/// This function partially implements Algorithm 6 of the NIST FIPS 203 standard, +-/// We say "partially" because this implementation only accepts a finite set of +-/// bytes as input and returns an error if the set is not enough; Algorithm 6 of +-/// the FIPS 203 standard on the other hand samples from an infinite stream of bytes +-/// until the ring element is filled. Algorithm 6 is reproduced below: +-/// ```plaintext +-/// Input: byte stream B ∈ 𝔹*. +-/// Output: array â ∈ ℤ₂₅₆. +-/// i ← 0 +-/// j ← 0 +-/// while j < 256 do +-/// d₁ ← B[i] + 256·(B[i+1] mod 16) +-/// d₂ ← ⌊B[i+1]/16⌋ + 16·B[i+2] +-/// if d₁ < q then +-/// â[j] ← d₁ +-/// j ← j + 1 +-/// end if +-/// if d₂ < q and j < 256 then +-/// â[j] ← d₂ +-/// j ← j + 1 +-/// end if +-/// i ← i + 3 +-/// end while +-/// return â +-/// ``` +-/// The NIST FIPS 203 standard can be found at +-/// . +-val sample_from_uniform_distribution_next +- (v_K v_N: usize) +- (randomness: t_Array (t_Array u8 v_N) v_K) +- (sampled_coefficients: t_Array usize v_K) +- (out: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- : Prims.Pure +- (t_Array usize v_K & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & bool) +- Prims.l_True +- (fun _ -> Prims.l_True) ++val sample_from_binomial_distribution (#p:Spec.Kyber.params) ++ (v_ETA: usize) (randomness: t_Slice u8) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1)) ++ (requires (v_ETA = p.v_ETA1 \/ v_ETA = p.v_ETA2) /\ ++ (Core.Slice.impl__len randomness <: usize) =. (v_ETA *! sz 64 <: usize)) ++ (ensures ++ fun result -> ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b result == ++ Spec.Kyber.sample_poly_binomial v_ETA randomness) + +-val sample_from_xof (v_K: usize) (seeds: t_Array (t_Array u8 (sz 34)) v_K) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) ++val sample_from_uniform_distribution (randomness: t_Array u8 (sz 840)) ++ : Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ (requires True) ++ (ensures fun _ -> True) ++// (ensures fun result -> (forall i. v (result.f_coefficients.[i]) >= 0)) ++ +diff -ruN extraction/Libcrux.Kem.Kyber.Serialize.fst extraction-edited/Libcrux.Kem.Kyber.Serialize.fst +--- extraction/Libcrux.Kem.Kyber.Serialize.fst 2024-05-14 15:56:45.392357040 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Serialize.fst 2024-05-14 15:56:45.454356023 +0200 +@@ -1,8 +1,15 @@ + module Libcrux.Kem.Kyber.Serialize +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++#set-options "--fuel 0 --ifuel 0 --z3rlimit 50 --retry 3" + open Core + open FStar.Mul + ++open Libcrux.Kem.Kyber.Arithmetic ++ ++open MkSeq ++open BitVecEq ++ ++#push-options "--z3rlimit 480 --split_queries always" ++[@@"opaque_to_smt"] + let compress_coefficients_10_ (coefficient1 coefficient2 coefficient3 coefficient4: i32) = + let coef1:u8 = cast (coefficient1 &. 255l <: i32) <: u8 in + let coef2:u8 = +@@ -18,12 +25,14 @@ + (cast ((coefficient3 >>! 4l <: i32) &. 63l <: i32) <: u8) in - re + let coef5:u8 = cast ((coefficient4 >>! 2l <: i32) &. 255l <: i32) <: u8 in ++ bit_vec_equal_intro_principle (); + coef1, coef2, coef3, coef4, coef5 <: (u8 & u8 & u8 & u8 & u8) +#pop-options -+#push-options "--z3rlimit 60" - let deserialize_then_decompress_message (serialized: t_Array u8 (sz 32)) = -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++#push-options "--ifuel 1 --z3rlimit 600 --split_queries always" ++[@@"opaque_to_smt"] + let compress_coefficients_11_ +- (coefficient1 coefficient2 coefficient3 coefficient4 coefficient5 coefficient6 coefficient7 coefficient8: +- i32) +- = ++ coefficient1 coefficient2 coefficient3 coefficient4 coefficient5 coefficient6 coefficient7 coefficient8 = + let coef1:u8 = cast (coefficient1 <: i32) <: u8 in + let coef2:u8 = + ((cast (coefficient2 &. 31l <: i32) <: u8) <>! 6l <: i32) <: u8) in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Iter.Traits.Collect.f_into_iter serialized -- <: -- Core.Array.Iter.t_IntoIter u8 (sz 32)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Array.Iter.t_IntoIter u8 (sz 32))) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Array.Iter.t_IntoIter u8 (sz 32))) -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Rust_primitives.Iterators.foldi_slice #_ #_ #(fun _ _ -> True) -+ serialized - re - (fun re temp_1_ -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in - let i, byte:(usize & u8) = temp_1_ in - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; -@@ -1151,10 +1235,11 @@ - Core.Ops.Range.t_Range usize) - re - (fun re j -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in - let j:usize = j in - let coefficient_compressed:i32 = cast ((byte >>! j <: u8) &. 1uy <: u8) <: i32 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ lemma_get_bit_bounded' coefficient_compressed 1; -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1168,19 +1253,20 @@ - i32) - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in - re) - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + let coef11:u8 = cast (coefficient8 >>! 3l <: i32) <: u8 in ++ bit_vec_equal_intro_principle (); + coef1, coef2, coef3, coef4, coef5, coef6, coef7, coef8, coef9, coef10, coef11 + <: + (u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8) ++#pop-options + +-let compress_coefficients_3_ (coefficient1 coefficient2: u16) = ++#push-options "--z3rlimit 20" ++[@@"opaque_to_smt"] ++let compress_coefficients_3_ coefficient1 coefficient2 = + let coef1:u8 = cast (coefficient1 &. 255us <: u16) <: u8 in ++ get_bit_pow2_minus_one_u16 255 (sz 0); + let coef2:u8 = + cast ((coefficient1 >>! 8l <: u16) |. ((coefficient2 &. 15us <: u16) <>! 4l <: u16) &. 255us <: u16) <: u8 in +- coef1, coef2, coef3 <: (u8 & u8 & u8) ++ bit_vec_equal_intro_principle (); ++ coef1, coef2, coef3 <: (u8 & u8 & u8) ++#pop-options + ++#push-options "--z3rlimit 160 --split_queries always" ++[@@"opaque_to_smt"] + let compress_coefficients_5_ +- (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: +- u8) +- = ++ coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8 ++ = + let coef1:u8 = ((coefficient2 &. 7uy <: u8) <>! 4l <: u8) + in + let coef5:u8 = (coefficient8 <>! 2l <: u8) in ++ bit_vec_equal_intro_principle (); + coef1, coef2, coef3, coef4, coef5 <: (u8 & u8 & u8 & u8 & u8) ++#pop-options + +-let decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: i32) = ++#push-options "--z3rlimit 500" ++[@@"opaque_to_smt"] ++let decompress_coefficients_10_ byte2 byte1 byte3 byte4 byte5 = + let coefficient1:i32 = ((byte2 &. 3l <: i32) <>! 2l <: i32) in + let coefficient3:i32 = ((byte4 &. 63l <: i32) <>! 4l <: i32) in + let coefficient4:i32 = (byte5 <>! 6l <: i32) in +- coefficient1, coefficient2, coefficient3, coefficient4 <: (i32 & i32 & i32 & i32) ++ lemma_get_bit_bounded' coefficient1 10; ++ lemma_get_bit_bounded' coefficient2 10; ++ lemma_get_bit_bounded' coefficient3 10; ++ lemma_get_bit_bounded' coefficient4 10; ++ bit_vec_equal_intro_principle (); ++ coefficient1, coefficient2, coefficient3, coefficient4 ++#pop-options + ++#push-options "--z3rlimit 300" ++[@@"opaque_to_smt"] + let decompress_coefficients_11_ +- (byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11: i32) +- = ++ byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11 = + let coefficient1:i32 = ((byte2 &. 7l <: i32) <>! 3l <: i32) in + let coefficient3:i32 = +@@ -109,6 +137,15 @@ + in + let coefficient7:i32 = ((byte10 &. 31l <: i32) <>! 2l <: i32) in + let coefficient8:i32 = (byte11 <>! 5l <: i32) in ++ bit_vec_equal_intro_principle (); ++ lemma_get_bit_bounded' coefficient1 11; ++ lemma_get_bit_bounded' coefficient2 11; ++ lemma_get_bit_bounded' coefficient3 11; ++ lemma_get_bit_bounded' coefficient4 11; ++ lemma_get_bit_bounded' coefficient5 11; ++ lemma_get_bit_bounded' coefficient6 11; ++ lemma_get_bit_bounded' coefficient7 11; ++ lemma_get_bit_bounded' coefficient8 11; + coefficient1, + coefficient2, + coefficient3, +@@ -117,15 +154,22 @@ + coefficient6, + coefficient7, + coefficient8 +- <: +- (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) ++#pop-options + +-let decompress_coefficients_4_ (byte: u8) = ++#push-options "--z3rlimit 50" ++[@@"opaque_to_smt"] ++let decompress_coefficients_4_ byte = + let coefficient1:i32 = cast (byte &. 15uy <: u8) <: i32 in + let coefficient2:i32 = cast ((byte >>! 4l <: u8) &. 15uy <: u8) <: i32 in +- coefficient1, coefficient2 <: (i32 & i32) +- +-let decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: i32) = ++ lemma_get_bit_bounded' coefficient1 4; ++ lemma_get_bit_bounded' coefficient2 4; ++ bit_vec_equal_intro_principle (); ++ coefficient1, coefficient2 ++#pop-options ++ ++#push-options "--z3rlimit 400" ++[@@"opaque_to_smt"] ++let decompress_coefficients_5_ byte1 byte2 byte3 byte4 byte5 = + let coefficient1:i32 = byte1 &. 31l in + let coefficient2:i32 = ((byte2 &. 3l <: i32) <>! 5l <: i32) in + let coefficient3:i32 = (byte2 >>! 2l <: i32) &. 31l in +@@ -134,6 +178,15 @@ + let coefficient6:i32 = (byte4 >>! 1l <: i32) &. 31l in + let coefficient7:i32 = ((byte5 &. 7l <: i32) <>! 6l <: i32) in + let coefficient8:i32 = byte5 >>! 3l in ++ bit_vec_equal_intro_principle (); ++ lemma_get_bit_bounded' coefficient1 5; ++ lemma_get_bit_bounded' coefficient2 5; ++ lemma_get_bit_bounded' coefficient3 5; ++ lemma_get_bit_bounded' coefficient4 5; ++ lemma_get_bit_bounded' coefficient5 5; ++ lemma_get_bit_bounded' coefficient6 5; ++ lemma_get_bit_bounded' coefficient7 5; ++ lemma_get_bit_bounded' coefficient8 5; + coefficient1, + coefficient2, + coefficient3, +@@ -142,31 +195,54 @@ + coefficient6, + coefficient7, + coefficient8 +- <: +- (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) ++#pop-options ++ ++let cast_bound_lemma ++ #t #u ++ (n: int_t t) ++ (d: num_bits t) ++ : Lemma (requires bounded n d /\ d <= bits u /\ unsigned u /\ v n >= 0) ++ (ensures bounded (cast #(int_t t) #(int_t u) n) d) ++ [SMTPat (bounded n d); SMTPat (cast #(int_t t) #(int_t u) n)] ++ = () ++ ++#push-options "--z3rlimit 90" ++[@@"opaque_to_smt"] ++let int_t_d_cast_lemma #t #u d (n: int_t_d t d) ++ : Lemma (requires bits t < bits u /\ v n >= 0) ++ (ensures bounded (cast #(int_t t) #(int_t u) n) d) ++ [SMTPat (bounded (cast #(int_t t) #(int_t u) n) d)] ++ = Math.Lemmas.pow2_double_mult (bits u - 1); ++ Math.Lemmas.small_mod (v n) (modulus u) ++let mul_in_range (n m: nat) ++ : Lemma ++ (requires n <= 256 /\ m <= 256) ++ (ensures range (n * m) usize_inttype) ++ = Math.Lemmas.pow2_plus 8 8; ++ Math.Lemmas.pow2_le_compat 32 16 +#pop-options --let deserialize_then_decompress_ring_element_u -- (v_COMPRESSION_FACTOR: usize) -- (serialized: t_Slice u8) -- = -+let deserialize_then_decompress_ring_element_u v_COMPRESSION_FACTOR serialized = - let _:Prims.unit = () <: Prims.unit in -+ mk_int_equiv_lemma #usize_inttype (v v_COMPRESSION_FACTOR); -+ assert (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 10 \/ v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 11); - match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 10ul -> deserialize_then_decompress_10_ serialized - | 11ul -> deserialize_then_decompress_11_ serialized -@@ -1190,11 +1276,11 @@ - <: - Rust_primitives.Hax.t_Never) - --let deserialize_then_decompress_ring_element_v -- (v_COMPRESSION_FACTOR: usize) -- (serialized: t_Slice u8) ++#restart-solver ++ ++#push-options "--fuel 0 --ifuel 1 --query_stats --z3rlimit 100" ++[@@"opaque_to_smt"] + let compress_then_serialize_10_ +- (v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) - = -+let deserialize_then_decompress_ring_element_v v_COMPRESSION_FACTOR serialized = - let _:Prims.unit = () <: Prims.unit in -+ mk_int_equiv_lemma #u32_inttype (v v_COMPRESSION_FACTOR); -+ assert (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 4 \/ v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 5); -+ let res = - match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with - | 4ul -> deserialize_then_decompress_4_ serialized - | 5ul -> deserialize_then_decompress_5_ serialized -@@ -1203,28 +1289,32 @@ - - <: - Rust_primitives.Hax.t_Never) ++ v_OUT_LEN ++ re ++ = ++ let accT = t_Array u8 v_OUT_LEN in ++ let inv = fun (acc: t_Array u8 v_OUT_LEN) (i: usize) -> ++ True + in -+ admit(); //P-F -+ res - --let deserialize_to_reduced_ring_element (ring_element: t_Slice u8) = -+#push-options "--z3rlimit 220" -+let deserialize_to_uncompressed_ring_element (serialized: t_Slice u8) = - let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = + let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in + let serialized:t_Array u8 v_OUT_LEN = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact ring_element (sz 3) <: Core.Slice.Iter.t_ChunksExact u8 -- ) +- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- (sz 4) +- <: +- Core.Slice.Iter.t_ChunksExact i32) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) - <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #(fun _ _ -> True) -+ serialized -+ (sz 3) - re - (fun re temp_1_ -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- let i, bytes:(usize & t_Slice u8) = temp_1_ in -- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in -+ let i, bytes:(usize & t_Array u8 (sz 3)) = temp_1_ in -+ let byte1:int_t_d i32_inttype 8 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -+ let byte2:int_t_d i32_inttype 8 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -+ let byte3:int_t_d i32_inttype 8 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -+ let coef1 = (((byte2 &. 15l <: i32) <>! 4l <: i32) &. 15l <: i32) <: i32) in -+ lemma_get_bit_bounded' coef1 11; -+ lemma_get_bit_bounded' coef2 11; -+ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = - { - re with - Libcrux.Kem.Kyber.Arithmetic.f_coefficients -@@ -1232,186 +1322,102 @@ - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - (sz 2 *! i <: usize) -- (((byte2 &. 15l <: i32) <>! 4l <: i32) &. 15l <: i32) <: i32) -+ coef2 - } - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - in -- let tmp:i32 = -- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 2 *! i <: usize) +! sz 1 <: usize -- ] -- <: -- i32) %! -- 3329l -- in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- { -- re with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- ((sz 2 *! i <: usize) +! sz 1 <: usize) -- tmp -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- in - re) +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- serialized ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #accT #inv ++ (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) ++ (sz 4) ++ (serialized) + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUT_LEN = serialized in +- let i, coefficients:(usize & t_Slice i32) = temp_1_ in ++ let i, coefficients:(usize & _) = temp_1_ in + let coefficient1:i32 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 10uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] <: i32 +@@ -226,79 +302,96 @@ + serialized) in - re + serialized +#pop-options --let deserialize_ring_elements_reduced (v_PUBLIC_KEY_SIZE v_K: usize) (public_key: t_Slice u8) = -- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K -- in -- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact public_key -- Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT -- <: -- Core.Slice.Iter.t_ChunksExact u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- deserialized_pk -- (fun deserialized_pk temp_1_ -> -- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- deserialized_pk -- in -- let i, ring_element:(usize & t_Slice u8) = temp_1_ in -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize deserialized_pk -- i -- (deserialize_to_reduced_ring_element ring_element -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- <: -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- in -- deserialized_pk -+module A = Libcrux.Kem.Kyber.Arithmetic - --let deserialize_to_uncompressed_ring_element (serialized: t_Slice u8) = -- let _:Prims.unit = () <: Prims.unit in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO -- in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate -- (Core.Slice.impl__chunks_exact serialized (sz 3) <: Core.Slice.Iter.t_ChunksExact u8) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) -- re -- (fun re temp_1_ -> -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in -- let i, bytes:(usize & t_Slice u8) = temp_1_ in -- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in -- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in -- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in -- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = -- { -- re with -- Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re -- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients -- (sz 2 *! i <: usize) -- (((byte2 &. 15l <: i32) <>! 4l <: i32) &. 15l <: i32) <: i32) -- } -- <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- in -- re) -- in -- re ++#push-options "--fuel 0 --ifuel 0 --z3rlimit 30" +[@@"opaque_to_smt"] -+let update3 #n (s: t_Array 't n) (offset: usize {v offset + 3 <= v n}) (i0 i1 i2: 't) -+ : s': t_Array 't n { Seq.index s' (v offset + 0) == i0 -+ /\ Seq.index s' (v offset + 1) == i1 -+ /\ Seq.index s' (v offset + 2) == i2 -+ /\ (forall i. (i < v offset \/ i >= v offset + 3) ==> Seq.index s' i == Seq.index s i) } ++let update5 ++ #n ++ (s: t_Array 't n) ++ (offset: usize {v offset + 5 <= v n}) ++ (i0 i1 i2 i3 i4: 't) ++ : s': t_Array 't n { ++ Seq.index s' (v offset + 0) == i0 /\ ++ Seq.index s' (v offset + 1) == i1 /\ ++ Seq.index s' (v offset + 2) == i2 /\ ++ Seq.index s' (v offset + 3) == i3 /\ ++ Seq.index s' (v offset + 4) == i4 /\ ++ (forall i. (i < v offset \/ i >= v offset + 5) ==> Seq.index s' i == Seq.index s i) ++ } + = let open Rust_primitives.Hax.Monomorphized_update_at in -+ let s = update_at_usize s offset i0 in -+ let s = update_at_usize s (offset +! sz 1) i1 in -+ update_at_usize s (offset +! sz 2) i2 - --let serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = -- let serialized:t_Array u8 (sz 384) = Rust_primitives.Hax.repeat 0uy (sz 384) in -- let serialized:t_Array u8 (sz 384) = ++ let s = update_at_usize s offset i0 in ++ let s = update_at_usize s (offset +! sz 1) i1 in ++ let s = update_at_usize s (offset +! sz 2) i2 in ++ let s = update_at_usize s (offset +! sz 3) i3 in ++ let s = update_at_usize s (offset +! sz 4) i4 in ++ s ++#pop-options ++ ++#push-options "--fuel 0 --ifuel 1 --z3rlimit 100 --query_stats --split_queries no" + let compress_then_serialize_11_ +- (v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- = ++ v_OUT_LEN re ++ = ++ let inv = fun (acc: t_Array u8 v_OUT_LEN) (i: usize) -> True in + let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in + let serialized:t_Array u8 v_OUT_LEN = - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate - (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re - .Libcrux.Kem.Kyber.Arithmetic.f_coefficients - <: - t_Slice i32) -- (sz 2) +- (sz 8) - <: - Core.Slice.Iter.t_ChunksExact i32) - <: - Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -- <: -- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) -+let slice_map_lemma #t #u #n (f: t -> u) (arr: t_Array t n) -+ (start: nat) (len: nat {start + len <= v n}) -+ : Lemma ( Seq.slice (Spec.Kyber.map' f arr) start (start + len) -+ == Spec.Kyber.map' f (Seq.slice arr start (start + len)) -+ ) -+ = let f_arr = Spec.Kyber.map' f arr in -+ let lhs = Seq.slice f_arr start (start + len) in -+ let rhs = Spec.Kyber.map' f (Seq.slice arr start (start + len)) in -+ introduce forall i. Seq.index lhs i == Seq.index rhs i -+ with ( -+ Seq.lemma_index_slice f_arr start (start + len) i; -+ Seq.lemma_index_slice arr start (start + len) i; -+ let sz_i_start, sz_i = sz (i + start), sz i in -+ assert (Seq.index f_arr (v sz_i_start) == f (Seq.index arr (v (sz_i_start)))); -+ assert (Seq.index rhs (v sz_i) == f (Seq.index (Seq.slice arr start (start + len)) (v sz_i))) -+ ); -+ assert (Seq.equal lhs rhs) -+ -+#push-options "--z3rlimit 2800 --fuel 0 --ifuel 0 --retry 0 --split_queries no" -+let serialize_uncompressed_ring_element re = -+ let serialized: t_Array u8 (sz 384) = Rust_primitives.Hax.repeat 0uy (sz 384) in -+ let max = v (sz 384) * 8 in -+ assert (max == 256 * 12 /\ max == 384 * 8 /\ 128 * 2 * 12 == max); -+ assert (128 == v (length re.f_coefficients /! (sz 2))); -+ let serialized = -+ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ -+ #(fun serialized i -> -+ let i = v i in -+ i <= 128 /\ ( -+ let limit = i * 2 * 12 in -+ let coefficients: t_Array _ (sz 256) = Spec.Kyber.map' to_unsigned_representative re.f_coefficients in -+ bit_vec_sub (bit_vec_of_int_t_array serialized 8 ) 0 limit -+ == bit_vec_sub (bit_vec_of_int_t_array coefficients 12) 0 limit) -+ ) -+ (re.A.f_coefficients <: t_Array _ (sz 256)) -+ (sz 2) - serialized -- (fun serialized temp_1_ -> -- let serialized:t_Array u8 (sz 384) = serialized in -- let i, coefficients:(usize & t_Slice i32) = temp_1_ in -- let coefficient1:u16 = -- Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] <: i32) -- in -- let coefficient2:u16 = -- Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 1 ] <: i32) -- in -- let coef1, coef2, coef3:(u8 & u8 & u8) = -- compress_coefficients_3_ coefficient1 coefficient2 -- in -- let serialized:t_Array u8 (sz 384) = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized -- (sz 3 *! i <: usize) -- coef1 -- in -- let serialized:t_Array u8 (sz 384) = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized -- ((sz 3 *! i <: usize) +! sz 1 <: usize) -- coef2 -- in -- let serialized:t_Array u8 (sz 384) = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized -- ((sz 3 *! i <: usize) +! sz 2 <: usize) -- coef3 -- in -- serialized) -+ (fun serialized it -> let i, coefficients = it in -+ -+ let coefficient1 = A.to_unsigned_representative (coefficients.[ sz 0 ] <: i32) in -+ let coefficient2 = A.to_unsigned_representative (coefficients.[ sz 1 ] <: i32) in -+ let (coef1, coef2, coef3) = compress_coefficients_3_ coefficient1 coefficient2 in -+ let j = sz 3 *! i in -+ let serialized' = update3 serialized j coef1 coef2 coef3 in -+ assert ( Seq.slice serialized' (v j) (v j + 3) -+ `Seq.equal` Seq.slice (create3 (coef1, coef2, coef3)) 0 3); -+ bit_vec_equal_intro -+ (let coefficients: t_Array _ (sz 2) = Spec.Kyber.map' to_unsigned_representative coefficients in -+ bit_vec_of_int_t_array coefficients 12) -+ (retype (bit_vec_sub (bit_vec_of_int_t_array serialized' 8) (3 * v i * 8) (3 * 8))); -+ let full_coefficients: t_Array u16 (sz 256) = Spec.Kyber.map' to_unsigned_representative re.f_coefficients in -+ slice_map_lemma #_ #u16 to_unsigned_representative re.f_coefficients (v i * 2) 2; -+ bit_vec_equal_intro -+ (bit_vec_sub (bit_vec_of_int_t_array serialized' 8) 0 (v i * 2 * 12)) -+ (bit_vec_sub (bit_vec_of_int_t_array serialized 8 ) 0 (v i * 2 * 12)); -+ bit_vec_equal_extend (bit_vec_of_int_t_array serialized' 8) -+ (bit_vec_of_int_t_array full_coefficients 12) -+ 0 0 (v i * 2 * 12) (3 * 8); -+ serialized' <: t_Array u8 (sz 384)) - in - serialized -+#pop-options -+ -diff -ruN extraction/Libcrux.Kem.Kyber.Serialize.fsti extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti ---- extraction/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-07 18:38:45 -@@ -2,133 +2,188 @@ - #set-options "--fuel 0 --ifuel 1 --z3rlimit 15" - open Core - open FStar.Mul -+open MkSeq -+open BitVecEq - - val compress_coefficients_10_ (coefficient1 coefficient2 coefficient3 coefficient4: i32) -- : Prims.Pure (u8 & u8 & u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) -+ : Prims.Pure (u8 & u8 & u8 & u8 & u8) -+ (requires True) -+ (ensures fun tuple -> -+ int_t_array_bitwise_eq' -+ (create4 (coefficient1, coefficient2, coefficient3, coefficient4)) 10 -+ (create5 tuple) 8 -+ ) - - val compress_coefficients_11_ - (coefficient1 coefficient2 coefficient3 coefficient4 coefficient5 coefficient6 coefficient7 coefficient8: -- i32) -+ int_t_d i32_inttype 11) - : Prims.Pure (u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (requires True) -+ (ensures fun tuple -> -+ int_t_array_bitwise_eq' -+ (create8 (coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8)) 11 -+ (create11 tuple) 8 -+ ) - --val compress_coefficients_3_ (coefficient1 coefficient2: u16) -- : Prims.Pure (u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) -+val compress_coefficients_3_ (coefficient1 coefficient2: int_t_d u16_inttype 12) -+ : Prims.Pure (u8 & u8 & u8) -+ (requires True) -+ (ensures fun tuple -> -+ int_t_array_bitwise_eq' -+ (create2 (coefficient1, coefficient2)) 12 -+ (create3 tuple) 8 -+ ) - - val compress_coefficients_5_ -- (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: -- u8) -- : Prims.Pure (u8 & u8 & u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) -+ (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: int_t_d u8_inttype 5) -+ : Prims.Pure (u8 & u8 & u8 & u8 & u8) -+ (requires True) -+ (ensures fun tuple -> -+ int_t_array_bitwise_eq' -+ (create8 (coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8)) 5 -+ (create5 tuple) 8 -+ ) - --val decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: i32) -- : Prims.Pure (i32 & i32 & i32 & i32) Prims.l_True (fun _ -> Prims.l_True) -+private unfold type i32_d = int_t_d i32_inttype -+val decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: int_t_d i32_inttype 8) -+ : Prims.Pure (i32_d 10 & i32_d 10 & i32_d 10 & i32_d 10) -+ (requires True) -+ (ensures fun (r1, r2, r3, r4) -> -+ int_t_array_bitwise_eq' -+ (create5 (byte1, byte2, byte3, byte4, byte5)) 8 -+ (create4 #i32 (r1, r2, r3, r4)) 10 -+ ) - - val decompress_coefficients_11_ -- (byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11: i32) -- : Prims.Pure (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11: int_t_d i32_inttype 8) -+ : Prims.Pure (i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11) -+ (requires True) -+ (ensures fun (r1, r2, r3, r4, r5, r6, r7, r8) -> -+ int_t_array_bitwise_eq' -+ (create11 #i32 (byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8, byte9, byte10, byte11)) 8 -+ (create8 #i32 (r1, r2, r3, r4, r5, r6, r7, r8)) 11 -+ ) - - val decompress_coefficients_4_ (byte: u8) -- : Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) -+ : Prims.Pure (i32_d 4 & i32_d 4) -+ (requires True) -+ (ensures fun (r1, r2) -> -+ int_t_array_bitwise_eq' -+ (create1 byte) 8 -+ (create2 #i32 (r1, r2)) 4 -+ ) - --val decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: i32) -- : Prims.Pure (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) -- Prims.l_True -- (fun _ -> Prims.l_True) -+val decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: int_t_d i32_inttype 8) -+ : Prims.Pure (i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5) -+ (requires True) -+ (ensures fun (r1, r2, r3, r4, r5, r6, r7, r8) -> -+ int_t_array_bitwise_eq' -+ (create5 #i32 (byte1, byte2, byte3, byte4, byte5)) 8 -+ (create8 #i32 (r1, r2, r3, r4, r5, r6, r7, r8)) 5 -+ ) - - val compress_then_serialize_10_ -- (v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (v_OUT_LEN: usize {v v_OUT_LEN >= 320}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) - - val compress_then_serialize_11_ -- (v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (v_OUT_LEN: usize {v v_OUT_LEN >= 352}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv ++ (Rust_primitives.unsize re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) ++ (sz 8) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUT_LEN = serialized in +- let i, coefficients:(usize & t_Slice i32) = temp_1_ in +- let coefficient1:i32 = ++ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement (sz 8)) = temp_1_ in ++ let coefficient1 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] <: i32 + ) + <: + u16) + in +- let coefficient2:i32 = ++ let coefficient2 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 1 ] <: i32 + ) + <: + u16) + in +- let coefficient3:i32 = ++ let coefficient3 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 2 ] <: i32 + ) + <: + u16) + in +- let coefficient4:i32 = ++ let coefficient4 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 3 ] <: i32 + ) + <: + u16) + in +- let coefficient5:i32 = ++ let coefficient5 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 4 ] <: i32 + ) + <: + u16) + in +- let coefficient6:i32 = ++ let coefficient6 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 5 ] <: i32 + ) + <: + u16) + in +- let coefficient7:i32 = ++ let coefficient7 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 6 ] <: i32 + ) + <: + u16) + in +- let coefficient8:i32 = ++ let coefficient8 = + Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 11uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 7 ] <: i32 + ) +@@ -324,6 +417,8 @@ + coefficient7 + coefficient8 + in ++ assert_spinoff (v i < 32 ==> 11 * v i + 11 <= 32 * 11); ++ assert_spinoff (v i < 32 ==> range (v (sz 11) * v i) usize_inttype); + let serialized:t_Array u8 v_OUT_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 11 *! i <: usize) +@@ -382,29 +477,20 @@ + serialized) + in + serialized ++#pop-options - val compress_then_serialize_4_ +-let compress_then_serialize_4_ - (v_OUT_LEN: usize) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (v_OUT_LEN: usize {v v_OUT_LEN >= 128}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) +- = ++let compress_then_serialize_4_ v_OUT_LEN re = + let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in ++ let accT = t_Array u8 v_OUT_LEN in ++ let inv (acc: accT) (i: usize) = True in + let serialized:t_Array u8 v_OUT_LEN = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- (sz 2) +- <: +- Core.Slice.Iter.t_ChunksExact i32) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv ++ (Rust_primitives.unsize re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) ++ (sz 2) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUT_LEN = serialized in +- let i, coefficients:(usize & t_Slice i32) = temp_1_ in ++ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement (sz 2)) = temp_1_ in + let coefficient1:u8 = + cast (Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 4uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] +@@ -439,27 +525,20 @@ + serialized - val compress_then_serialize_5_ + let compress_then_serialize_5_ - (v_OUT_LEN: usize) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (v_OUT_LEN: usize {v v_OUT_LEN >= 160}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) - --val compress_then_serialize_message (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -+val compress_then_serialize_message (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ : Pure (t_Array u8 (sz 32)) -+ (requires True) -+ (ensures (fun res -> -+ res == Spec.Kyber.compress_then_encode_message (Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b re))) +- = ++ v_OUT_LEN ++ re ++ = + let serialized:t_Array u8 v_OUT_LEN = Rust_primitives.Hax.repeat 0uy v_OUT_LEN in ++ let accT = t_Array u8 v_OUT_LEN in ++ let inv (acc: accT) (i: usize) = True in + let serialized:t_Array u8 v_OUT_LEN = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- (sz 8) +- <: +- Core.Slice.Iter.t_ChunksExact i32) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv ++ (Rust_primitives.unsize re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) ++ (sz 8) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 v_OUT_LEN = serialized in +- let i, coefficients:(usize & t_Slice i32) = temp_1_ in ++ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement (sz 8)) = temp_1_ in + let coefficient1:u8 = + cast (Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 5uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] +@@ -544,6 +623,14 @@ + <: + u8 + in ++ let coefficient8' = Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 5uy ++ (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 7 ] ++ <: ++ i32) ++ <: ++ u16) ++ <: ++ i32 in + let coefficient8:u8 = + cast (Libcrux.Kem.Kyber.Compress.compress_ciphertext_coefficient 5uy + (Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 7 ] +@@ -566,6 +653,8 @@ + coefficient6 + coefficient8 + in ++ assert_spinoff (v i < 32 ==> 5 * v i + 5 <= 32 * 5); ++ assert_spinoff (v i < 32 ==> range (v (sz 5) * v i) usize_inttype); + let serialized:t_Array u8 v_OUT_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized + (sz 5 *! i <: usize) +@@ -595,35 +684,24 @@ + in + serialized - val compress_then_serialize_ring_element_u -- (v_COMPRESSION_FACTOR v_OUT_LEN: usize) -- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) -+ (#p:Spec.Kyber.params) -+ (v_COMPRESSION_FACTOR: usize {v v_COMPRESSION_FACTOR == 10 \/ v v_COMPRESSION_FACTOR == 11}) -+ (v_OUT_LEN: usize { v v_OUT_LEN = 32 * v v_COMPRESSION_FACTOR }) -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ : t_Array u8 v_OUT_LEN -+ -+val compress_then_serialize_ring_element_v (#p:Spec.Kyber.params) -+ (v_COMPRESSION_FACTOR: usize {v_COMPRESSION_FACTOR = sz 4 || v_COMPRESSION_FACTOR = sz 5}) -+ (v_OUT_LEN: usize {v v_OUT_LEN = 32 * v v_COMPRESSION_FACTOR}) -+ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ : Pure (t_Array u8 v_OUT_LEN) -+ (requires True) -+ (ensures (fun res -> -+ res == -+ Spec.Kyber.compress_then_encode_v p -+ (Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b re))) +-let compress_then_serialize_message (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = ++let compress_then_serialize_message re = + let serialized:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in ++ let accT = t_Array u8 (sz 32) in ++ let inv (acc: accT) (i: usize) = True in + let serialized:t_Array u8 (sz 32) = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- (sz 8) +- <: +- Core.Slice.Iter.t_ChunksExact i32) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv ++ (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients) ++ (sz 8) + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 32) = serialized in +- let i, coefficients:(usize & t_Slice i32) = temp_1_ in +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__iter coefficients <: Core.Slice.Iter.t_Iter i32) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter i32)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter i32)) ++ let i, coefficients:(usize & t_Array Libcrux.Kem.Kyber.Arithmetic.wfFieldElement _) = temp_1_ in ++ Rust_primitives.Iterators.foldi_slice #_ #_ #(fun _ _ -> True) ++ coefficients + serialized + (fun serialized temp_1_ -> + let serialized:t_Array u8 (sz 32) = serialized in +- let j, coefficient:(usize & i32) = temp_1_ in ++ let j, coefficient:(usize & Libcrux.Kem.Kyber.Arithmetic.wfFieldElement) = temp_1_ in + let coefficient:u16 = + Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative coefficient + in +@@ -636,27 +714,35 @@ + <: + t_Array u8 (sz 32)) + in ++ admit (); // P-F + serialized --val compress_then_serialize_ring_element_v +-let compress_then_serialize_ring_element_u - (v_COMPRESSION_FACTOR v_OUT_LEN: usize) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) -- --val deserialize_then_decompress_10_ (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+val deserialize_then_decompress_10_ (serialized: t_Slice u8 {Seq.length serialized == 320}) -+ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - Prims.l_True - (fun _ -> Prims.l_True) - --val deserialize_then_decompress_11_ (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+val deserialize_then_decompress_11_ (serialized: t_Slice u8 {Seq.length serialized == 352}) -+ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - Prims.l_True - (fun _ -> Prims.l_True) - --val deserialize_then_decompress_4_ (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+val deserialize_then_decompress_4_ (serialized: t_Slice u8 {Seq.length serialized == 128}) -+ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - Prims.l_True - (fun _ -> Prims.l_True) - --val deserialize_then_decompress_5_ (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+val deserialize_then_decompress_5_ -+ (serialized: t_Slice u8 {Seq.length serialized == 160}) -+ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement - Prims.l_True - (fun _ -> Prims.l_True) - - val deserialize_then_decompress_message (serialized: t_Array u8 (sz 32)) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires True) -+ (ensures fun res -> -+ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res == -+ Spec.Kyber.decode_then_decompress_message serialized) - - val deserialize_then_decompress_ring_element_u - (v_COMPRESSION_FACTOR: usize) -- (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+ (serialized: t_Slice u8 { -+ match v v_COMPRESSION_FACTOR with -+ | 10 -> Seq.length serialized == 320 -+ | 11 -> Seq.length serialized == 352 -+ | _ -> False -+ }) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires v_COMPRESSION_FACTOR = sz 10 || v_COMPRESSION_FACTOR = sz 11) -+ (ensures fun _ -> True) - --val deserialize_then_decompress_ring_element_v -- (v_COMPRESSION_FACTOR: usize) -+val deserialize_then_decompress_ring_element_v (#p:Spec.Kyber.params) -+ (v_COMPRESSION_FACTOR: usize {v v_COMPRESSION_FACTOR == 4 \/ v v_COMPRESSION_FACTOR == 5}) - (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires (p.v_VECTOR_V_COMPRESSION_FACTOR == v_COMPRESSION_FACTOR /\ -+ length serialized == Spec.Kyber.v_C2_SIZE p)) -+ (ensures fun res -> Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res -+ == Spec.Kyber.decode_then_decompress_v p serialized) - --/// Only use with public values. --/// This MUST NOT be used with secret inputs, like its caller `deserialize_ring_elements_reduced`. --val deserialize_to_reduced_ring_element (ring_element: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -- --/// This function deserializes ring elements and reduces the result by the field --/// modulus. --/// This function MUST NOT be used on secret inputs. --val deserialize_ring_elements_reduced (v_PUBLIC_KEY_SIZE v_K: usize) (public_key: t_Slice u8) -- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -- Prims.l_True -- (fun _ -> Prims.l_True) +- = ++let compress_then_serialize_ring_element_u #p ++ v_COMPRESSION_FACTOR ++ v_OUT_LEN ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) = + let _:Prims.unit = () <: Prims.unit in ++ assert ( ++ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 11) \/ ++ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 10) ++ ); ++ Rust_primitives.Integers.mk_int_equiv_lemma #usize_inttype (v v_COMPRESSION_FACTOR); + match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with + | 10ul -> compress_then_serialize_10_ v_OUT_LEN re + | 11ul -> compress_then_serialize_11_ v_OUT_LEN re + | _ -> + Rust_primitives.Hax.never_to_any (Core.Panicking.panic "internal error: entered unreachable code" - - val deserialize_to_uncompressed_ring_element (serialized: t_Slice u8) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ (requires (length serialized == Spec.Kyber.v_BYTES_PER_RING_ELEMENT)) -+ (ensures fun _ -> True) - --val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -- : Prims.Pure (t_Array u8 (sz 384)) Prims.l_True (fun _ -> Prims.l_True) -+val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -+ : Pure (t_Array u8 (sz 384)) -+ (requires True) -+ (ensures (fun res -> -+ let coefficients: t_Array _ (sz 256) = Spec.Kyber.map' Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative re.f_coefficients in -+ int_t_array_bitwise_eq res 8 coefficients 12 -+ )) -diff -ruN extraction/Libcrux.Kem.Kyber.Types.fst extraction-edited/Libcrux.Kem.Kyber.Types.fst ---- extraction/Libcrux.Kem.Kyber.Types.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.Types.fst 2024-05-07 18:38:45 -@@ -40,13 +40,41 @@ - f_from = fun (value: t_MlKemCiphertext v_SIZE) -> value.f_value - } + <: + Rust_primitives.Hax.t_Never) -+[@@ FStar.Tactics.Typeclasses.tcinstance] -+let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = -+ { -+ f_Error = Core.Array.t_TryFromSliceError; -+ f_try_from_pre = (fun (value: t_Slice u8) -> true); -+ f_try_from_post -+ = -+ (fun -+ (value: t_Slice u8) -+ (out: Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError) -+ -> -+ true); -+ f_try_from -+ = -+ fun (value: t_Slice u8) -> -+ match Core.Convert.f_try_into value with -+ | Core.Result.Result_Ok value -> -+ Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) -+ <: -+ Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError -+ | Core.Result.Result_Err e -> -+ Core.Result.Result_Err e -+ <: -+ Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError -+ } -+ - let impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : t_Array u8 v_SIZE = - self.f_value +-let compress_then_serialize_ring_element_v +- (v_COMPRESSION_FACTOR v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- = ++let compress_then_serialize_ring_element_v #p v_COMPRESSION_FACTOR v_OUT_LEN re = + let _:Prims.unit = () <: Prims.unit in ++ Rust_primitives.Integers.mk_int_equiv_lemma #usize_inttype (v v_COMPRESSION_FACTOR); ++ let res = ++ assert ( ++ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 4) \/ ++ (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 5) ++ ); + match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with + | 4ul -> compress_then_serialize_4_ v_OUT_LEN re + | 5ul -> compress_then_serialize_5_ v_OUT_LEN re +@@ -665,32 +751,49 @@ - let impl_6__len (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : usize = v_SIZE + <: + Rust_primitives.Hax.t_Never) ++ in ++ admit (); // P-F ++ res - let impl_6__split_at (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) (mid: usize) -- : (t_Slice u8 & t_Slice u8) = -+ : Pure (t_Slice u8 & t_Slice u8) -+ (requires (mid <=. v_SIZE)) -+ (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid +-let deserialize_then_decompress_10_ (serialized: t_Slice u8) = ++#push-options "--z3rlimit 160" ++let deserialize_then_decompress_10_ serialized = + let _:Prims.unit = () <: Prims.unit in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact serialized (sz 5) <: Core.Slice.Iter.t_ChunksExact u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ let accT = Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement in ++ let inv (acc: accT) (i: usize) = True in ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #inv ++ serialized ++ (sz 5) + re + (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- let i, bytes:(usize & t_Slice u8) = temp_1_ in +- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in +- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in +- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in +- let byte4:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in +- let byte5:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in +- let coefficient1, coefficient2, coefficient3, coefficient4:(i32 & i32 & i32 & i32) = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in ++ let i, bytes:(usize & t_Array u8 (sz 5)) = temp_1_ in ++ let byte1: int_t_d i32_inttype 8 = cast (bytes.[ sz 0 ] <: u8) <: i32 in ++ let byte2: int_t_d i32_inttype 8 = cast (bytes.[ sz 1 ] <: u8) <: i32 in ++ let byte3: int_t_d i32_inttype 8 = cast (bytes.[ sz 2 ] <: u8) <: i32 in ++ let byte4: int_t_d i32_inttype 8 = cast (bytes.[ sz 3 ] <: u8) <: i32 in ++ let byte5: int_t_d i32_inttype 8 = cast (bytes.[ sz 4 ] <: u8) <: i32 in ++ let coefficient1, coefficient2, coefficient3, coefficient4 = + decompress_coefficients_10_ byte2 byte1 byte3 byte4 byte5 + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let coefficient1 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient1 ++ <: ++ i32) in ++ let coefficient2 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient2 ++ <: ++ i32) in ++ let coefficient3 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient3 ++ <: ++ i32) in ++ let coefficient4 = (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient4 ++ <: ++ i32) in ++ assert_spinoff (v i < 64 ==> 4 * v i + 4 <= 256); ++ assert_spinoff (v i < 64 ==> range (v (sz 4) * v i) usize_inttype); ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -698,14 +801,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + (sz 4 *! i <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient1 +- <: +- i32) ++ coefficient1 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -713,14 +814,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 4 *! i <: usize) +! sz 1 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient2 +- <: +- i32) ++ coefficient2 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -728,14 +827,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 4 *! i <: usize) +! sz 2 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient3 +- <: +- i32) ++ coefficient3 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -743,44 +840,43 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 4 *! i <: usize) +! sz 3 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 10uy coefficient4 +- <: +- i32) ++ coefficient4 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in + re) + in + re ++#pop-options - type t_MlKemPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } -@@ -86,15 +114,53 @@ - f_from = fun (value: t_MlKemPrivateKey v_SIZE) -> value.f_value - } +-let deserialize_then_decompress_11_ (serialized: t_Slice u8) = ++#push-options "--z3rlimit 100 --ifuel 0" ++let deserialize_then_decompress_11_ serialized ++ : Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + let _:Prims.unit = () <: Prims.unit in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact serialized (sz 11) <: Core.Slice.Iter.t_ChunksExact u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #(fun _ _ -> True) ++ serialized ++ (sz 11) + re + (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- let i, bytes:(usize & t_Slice u8) = temp_1_ in +- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in +- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in +- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in +- let byte4:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in +- let byte5:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in +- let byte6:i32 = cast (bytes.[ sz 5 ] <: u8) <: i32 in +- let byte7:i32 = cast (bytes.[ sz 6 ] <: u8) <: i32 in +- let byte8:i32 = cast (bytes.[ sz 7 ] <: u8) <: i32 in +- let byte9:i32 = cast (bytes.[ sz 8 ] <: u8) <: i32 in +- let byte10:i32 = cast (bytes.[ sz 9 ] <: u8) <: i32 in +- let byte11:i32 = cast (bytes.[ sz 10 ] <: u8) <: i32 in ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in ++ let i, bytes:(usize & t_Array u8 (sz 11)) = temp_1_ in ++ assert (v i < 32); ++ let byte1: int_t_d i32_inttype 8 = cast (bytes.[ sz 0 ] <: u8) <: i32 in ++ let byte2: int_t_d i32_inttype 8 = cast (bytes.[ sz 1 ] <: u8) <: i32 in ++ let byte3: int_t_d i32_inttype 8 = cast (bytes.[ sz 2 ] <: u8) <: i32 in ++ let byte4: int_t_d i32_inttype 8 = cast (bytes.[ sz 3 ] <: u8) <: i32 in ++ let byte5: int_t_d i32_inttype 8 = cast (bytes.[ sz 4 ] <: u8) <: i32 in ++ let byte6: int_t_d i32_inttype 8 = cast (bytes.[ sz 5 ] <: u8) <: i32 in ++ let byte7: int_t_d i32_inttype 8 = cast (bytes.[ sz 6 ] <: u8) <: i32 in ++ let byte8: int_t_d i32_inttype 8 = cast (bytes.[ sz 7 ] <: u8) <: i32 in ++ let byte9: int_t_d i32_inttype 8 = cast (bytes.[ sz 8 ] <: u8) <: i32 in ++ let byte10: int_t_d i32_inttype 8 = cast (bytes.[ sz 9 ] <: u8) <: i32 in ++ let byte11: int_t_d i32_inttype 8 = cast (bytes.[ sz 10 ] <: u8) <: i32 in + let + coefficient1, + coefficient2, +@@ -789,11 +885,21 @@ + coefficient5, + coefficient6, + coefficient7, +- coefficient8:(i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) = ++ coefficient8 = + decompress_coefficients_11_ byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 + byte11 + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let coefficient1 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient1 in ++ let coefficient2 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient2 in ++ let coefficient3 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient3 in ++ let coefficient4 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient4 in ++ let coefficient5 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient5 in ++ let coefficient6 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient6 in ++ let coefficient7 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient7 in ++ let coefficient8 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient8 in ++ assert_spinoff (8 * v i + 8 <= 256); ++ assert_spinoff (range (v (sz 8) * v i) usize_inttype); ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -801,14 +907,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + (sz 8 *! i <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient1 +- <: +- i32) ++ coefficient1 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -816,14 +920,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 1 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient2 +- <: +- i32) ++ coefficient2 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -831,14 +933,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 2 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient3 +- <: +- i32) ++ coefficient3 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -846,14 +946,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 3 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient4 +- <: +- i32) ++ coefficient4 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -861,14 +959,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 4 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient5 +- <: +- i32) ++ coefficient5 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -876,14 +972,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 5 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient6 +- <: +- i32) ++ coefficient6 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -891,14 +985,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 6 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient7 +- <: +- i32) ++ coefficient7 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -906,35 +998,33 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 7 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 11uy coefficient8 +- <: +- i32) ++ coefficient8 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in + re) + in + re ++#pop-options -+[@@ FStar.Tactics.Typeclasses.tcinstance] -+let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = -+ { -+ f_Error = Core.Array.t_TryFromSliceError; -+ f_try_from_pre = (fun (value: t_Slice u8) -> true); -+ f_try_from_post -+ = -+ (fun -+ (value: t_Slice u8) -+ (out: Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError) -+ -> -+ true); -+ f_try_from -+ = -+ fun (value: t_Slice u8) -> -+ match Core.Convert.f_try_into value with -+ | Core.Result.Result_Ok value -> -+ Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) -+ <: -+ Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError -+ | Core.Result.Result_Err e -> -+ Core.Result.Result_Err e -+ <: -+ Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError -+ } -+ - let impl_12__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : t_Array u8 v_SIZE = - self.f_value +-let deserialize_then_decompress_4_ (serialized: t_Slice u8) = ++#push-options "--z3rlimit 100" ++let deserialize_then_decompress_4_ serialized = + let _:Prims.unit = () <: Prims.unit in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__iter serialized <: Core.Slice.Iter.t_Iter u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter u8)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_Iter u8)) ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Rust_primitives.Iterators.foldi_slice #_ #_ #(fun _ _ -> True) ++ serialized + re + (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in + let i, byte:(usize & u8) = temp_1_ in +- let coefficient1, coefficient2:(i32 & i32) = decompress_coefficients_4_ byte in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let coefficient1, coefficient2 = decompress_coefficients_4_ byte in ++ assert_spinoff (v i < 128 ==> 2 * v i + 1 < 256); ++ assert_spinoff (v i < 128 ==> range (v (sz 2) * v i) usize_inttype); ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -947,9 +1037,9 @@ + i32) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -962,33 +1052,32 @@ + i32) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in + re) + in + re ++#pop-options - let impl_12__len (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : usize = v_SIZE +-let deserialize_then_decompress_5_ (serialized: t_Slice u8) = ++#push-options "--z3rlimit 150" ++let deserialize_then_decompress_5_ serialized = + let _:Prims.unit = () <: Prims.unit in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact serialized (sz 5) <: Core.Slice.Iter.t_ChunksExact u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #(fun _ _ -> True) ++ serialized (sz 5) + re + (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- let i, bytes:(usize & t_Slice u8) = temp_1_ in +- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in +- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in +- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in +- let byte4:i32 = cast (bytes.[ sz 3 ] <: u8) <: i32 in +- let byte5:i32 = cast (bytes.[ sz 4 ] <: u8) <: i32 in ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in ++ let i, bytes:(usize & t_Array u8 (sz 5)) = temp_1_ in ++ assert (v i < 32); ++ let byte1 = cast (bytes.[ sz 0 ] <: u8) <: i32 in ++ let byte2 = cast (bytes.[ sz 1 ] <: u8) <: i32 in ++ let byte3 = cast (bytes.[ sz 2 ] <: u8) <: i32 in ++ let byte4 = cast (bytes.[ sz 3 ] <: u8) <: i32 in ++ let byte5 = cast (bytes.[ sz 4 ] <: u8) <: i32 in + let + coefficient1, + coefficient2, +@@ -997,10 +1086,25 @@ + coefficient5, + coefficient6, + coefficient7, +- coefficient8:(i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) = ++ coefficient8 = + decompress_coefficients_5_ byte1 byte2 byte3 byte4 byte5 + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let coefficient1 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient1 in ++ let coefficient2 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient2 in ++ let coefficient3 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient3 in ++ let coefficient4 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient4 in ++ let coefficient5 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient5 in ++ let coefficient6 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient6 in ++ let coefficient7 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient7 in ++ let coefficient8 = Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient8 in ++ // assert (Seq.length serialized == 160); ++ // // assert_norm (160 / 5 == 32); ++ // assert_spinoff (v i < Seq.length serialized); ++ // assert (v i < 32); ++ assert_spinoff (v i < 32 ==> 8 * v i + 8 <= 256); ++ mul_in_range 8 (v i); ++ assert_spinoff (v i < 32 ==> range (v (sz 8) * v i) usize_inttype); ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1008,14 +1112,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + (sz 8 *! i <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient1 +- <: +- i32) ++ coefficient1 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1023,14 +1125,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 1 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient2 +- <: +- i32) ++ coefficient2 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1038,14 +1138,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 2 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient3 +- <: +- i32) ++ coefficient3 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1053,14 +1151,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 3 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient4 +- <: +- i32) ++ coefficient4 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1068,14 +1164,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 4 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient5 +- <: +- i32) ++ coefficient5 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1083,14 +1177,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 5 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient6 +- <: +- i32) ++ coefficient6 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1098,14 +1190,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 6 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient7 +- <: +- i32) ++ coefficient7 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1113,33 +1203,27 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + ((sz 8 *! i <: usize) +! sz 7 <: usize) +- (Libcrux.Kem.Kyber.Compress.decompress_ciphertext_coefficient 5uy coefficient8 +- <: +- i32) ++ coefficient8 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in + re) + in + re ++#pop-options - let impl_12__split_at (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) (mid: usize) -- : (t_Slice u8 & t_Slice u8) = -+ : Pure (t_Slice u8 & t_Slice u8) -+ (requires (mid <=. v_SIZE)) -+ (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid ++#push-options "--z3rlimit 60" + let deserialize_then_decompress_message (serialized: t_Array u8 (sz 32)) = +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Iter.Traits.Collect.f_into_iter serialized +- <: +- Core.Array.Iter.t_IntoIter u8 (sz 32)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Array.Iter.t_IntoIter u8 (sz 32))) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Array.Iter.t_IntoIter u8 (sz 32))) ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Rust_primitives.Iterators.foldi_slice #_ #_ #(fun _ _ -> True) ++ serialized + re + (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in + let i, byte:(usize & u8) = temp_1_ in + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; +@@ -1151,10 +1235,11 @@ + Core.Ops.Range.t_Range usize) + re + (fun re j -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in + let j:usize = j in + let coefficient_compressed:i32 = cast ((byte >>! j <: u8) &. 1uy <: u8) <: i32 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ lemma_get_bit_bounded' coefficient_compressed 1; ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1168,19 +1253,20 @@ + i32) + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in + re) + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + in ++ admit(); //P-F + re ++#pop-options -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - type t_MlKemPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } +-let deserialize_then_decompress_ring_element_u +- (v_COMPRESSION_FACTOR: usize) +- (serialized: t_Slice u8) +- = ++let deserialize_then_decompress_ring_element_u v_COMPRESSION_FACTOR serialized = + let _:Prims.unit = () <: Prims.unit in ++ mk_int_equiv_lemma #usize_inttype (v v_COMPRESSION_FACTOR); ++ assert (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 10 \/ v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 11); + match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with + | 10ul -> deserialize_then_decompress_10_ serialized + | 11ul -> deserialize_then_decompress_11_ serialized +@@ -1190,11 +1276,11 @@ + <: + Rust_primitives.Hax.t_Never) - [@@ FStar.Tactics.Typeclasses.tcinstance] -@@ -132,68 +198,7 @@ - f_from = fun (value: t_MlKemPublicKey v_SIZE) -> value.f_value - } +-let deserialize_then_decompress_ring_element_v +- (v_COMPRESSION_FACTOR: usize) +- (serialized: t_Slice u8) +- = ++let deserialize_then_decompress_ring_element_v v_COMPRESSION_FACTOR serialized = + let _:Prims.unit = () <: Prims.unit in ++ mk_int_equiv_lemma #u32_inttype (v v_COMPRESSION_FACTOR); ++ assert (v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 4 \/ v (cast (v_COMPRESSION_FACTOR <: usize) <: u32) == 5); ++ let res = + match cast (v_COMPRESSION_FACTOR <: usize) <: u32 with + | 4ul -> deserialize_then_decompress_4_ serialized + | 5ul -> deserialize_then_decompress_5_ serialized +@@ -1203,143 +1289,32 @@ --let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : t_Array u8 v_SIZE = -- self.f_value -- --let impl_18__len (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : usize = v_SIZE -- --let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) -- : (t_Slice u8 & t_Slice u8) = -- Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid + <: + Rust_primitives.Hax.t_Never) - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = -- { -- f_Error = Core.Array.t_TryFromSliceError; -- f_try_from_pre = (fun (value: t_Slice u8) -> true); -- f_try_from_post -- = -- (fun -- (value: t_Slice u8) -- (out: Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError) -- -> -- true); -- f_try_from -- = -- fun (value: t_Slice u8) -> -- match Core.Convert.f_try_into value with -- | Core.Result.Result_Ok value -> -- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) -- <: -- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError -- | Core.Result.Result_Err e -> -- Core.Result.Result_Err e +-let deserialize_to_reduced_ring_element (ring_element: t_Slice u8) = +- let _:Prims.unit = () <: Prims.unit in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact ring_element (sz 3) <: Core.Slice.Iter.t_ChunksExact u8 +- ) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) - <: -- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError -- } +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- re +- (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- let i, bytes:(usize & t_Slice u8) = temp_1_ in +- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in +- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in +- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- { +- re with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- (sz 2 *! i <: usize) +- (((byte2 &. 15l <: i32) <>! 4l <: i32) &. 15l <: i32) <: i32) +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- in +- let tmp:i32 = +- (re.Libcrux.Kem.Kyber.Arithmetic.f_coefficients.[ (sz 2 *! i <: usize) +! sz 1 <: usize +- ] +- <: +- i32) %! +- 3329l +- in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- { +- re with +- Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- ((sz 2 *! i <: usize) +! sz 1 <: usize) +- tmp +- } +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- in +- re) +- in +- re - --[@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = -- { -- f_Error = Core.Array.t_TryFromSliceError; -- f_try_from_pre = (fun (value: t_Slice u8) -> true); -- f_try_from_post -- = -- (fun -- (value: t_Slice u8) -- (out: Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError) -- -> -- true); -- f_try_from -- = -- fun (value: t_Slice u8) -> -- match Core.Convert.f_try_into value with -- | Core.Result.Result_Ok value -> -- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) +-let deserialize_ring_elements_reduced (v_PUBLIC_KEY_SIZE v_K: usize) (public_key: t_Slice u8) = +- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K +- in +- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact public_key +- Libcrux.Kem.Kyber.Constants.v_BYTES_PER_RING_ELEMENT +- <: +- Core.Slice.Iter.t_ChunksExact u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) - <: -- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError -- | Core.Result.Result_Err e -> -- Core.Result.Result_Err e +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) +- deserialized_pk +- (fun deserialized_pk temp_1_ -> +- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = +- deserialized_pk +- in +- let i, ring_element:(usize & t_Slice u8) = temp_1_ in +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize deserialized_pk +- i +- (deserialize_to_reduced_ring_element ring_element +- <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- <: +- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- in +- deserialized_pk ++ admit(); //P-F ++ res + +-let deserialize_to_uncompressed_ring_element (serialized: t_Slice u8) = ++#push-options "--z3rlimit 220" ++let deserialize_to_uncompressed_ring_element (serialized: t_Slice u8) = + let _:Prims.unit = () <: Prims.unit in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO + in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact serialized (sz 3) <: Core.Slice.Iter.t_ChunksExact u8) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) - <: -- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError -- } -- --[@@ FStar.Tactics.Typeclasses.tcinstance] - let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) (t_Slice u8) = - { - f_Error = Core.Array.t_TryFromSliceError; -@@ -219,7 +224,17 @@ - Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError - } +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact u8)) ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ #(fun _ _ -> True) ++ serialized ++ (sz 3) + re + (fun re temp_1_ -> +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = re in +- let i, bytes:(usize & t_Slice u8) = temp_1_ in +- let byte1:i32 = cast (bytes.[ sz 0 ] <: u8) <: i32 in +- let byte2:i32 = cast (bytes.[ sz 1 ] <: u8) <: i32 in +- let byte3:i32 = cast (bytes.[ sz 2 ] <: u8) <: i32 in +- let re:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = re in ++ let i, bytes:(usize & t_Array u8 (sz 3)) = temp_1_ in ++ let byte1:int_t_d i32_inttype 8 = cast (bytes.[ sz 0 ] <: u8) <: i32 in ++ let byte2:int_t_d i32_inttype 8 = cast (bytes.[ sz 1 ] <: u8) <: i32 in ++ let byte3:int_t_d i32_inttype 8 = cast (bytes.[ sz 2 ] <: u8) <: i32 in ++ let coef1 = (((byte2 &. 15l <: i32) <>! 4l <: i32) &. 15l <: i32) <: i32) in ++ lemma_get_bit_bounded' coef1 11; ++ lemma_get_bit_bounded' coef2 11; ++ let re:Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = + { + re with + Libcrux.Kem.Kyber.Arithmetic.f_coefficients +@@ -1347,12 +1322,12 @@ + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize re + .Libcrux.Kem.Kyber.Arithmetic.f_coefficients + (sz 2 *! i <: usize) +- (((byte2 &. 15l <: i32) <>! 4l <: i32) &. 15l <: i32) <: i32) ++ coef2 + } + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + in + re) + in + re ++#pop-options --/// An ML-KEM key pair -+let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : t_Array u8 v_SIZE = -+ self.f_value +-let serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) = +- let serialized:t_Array u8 (sz 384) = Rust_primitives.Hax.repeat 0uy (sz 384) in +- let serialized:t_Array u8 (sz 384) = +- Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate +- (Core.Slice.impl__chunks_exact (Rust_primitives.unsize re +- .Libcrux.Kem.Kyber.Arithmetic.f_coefficients +- <: +- t_Slice i32) +- (sz 2) +- <: +- Core.Slice.Iter.t_ChunksExact i32) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) +- <: +- Core.Iter.Adapters.Enumerate.t_Enumerate (Core.Slice.Iter.t_ChunksExact i32)) ++module A = Libcrux.Kem.Kyber.Arithmetic + -+let impl_18__len (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : usize = v_SIZE ++[@@"opaque_to_smt"] ++let update3 #n (s: t_Array 't n) (offset: usize {v offset + 3 <= v n}) (i0 i1 i2: 't) ++ : s': t_Array 't n { Seq.index s' (v offset + 0) == i0 ++ /\ Seq.index s' (v offset + 1) == i1 ++ /\ Seq.index s' (v offset + 2) == i2 ++ /\ (forall i. (i < v offset \/ i >= v offset + 3) ==> Seq.index s' i == Seq.index s i) } ++ = let open Rust_primitives.Hax.Monomorphized_update_at in ++ let s = update_at_usize s offset i0 in ++ let s = update_at_usize s (offset +! sz 1) i1 in ++ update_at_usize s (offset +! sz 2) i2 ++ ++let slice_map_lemma #t #u #n (f: t -> u) (arr: t_Array t n) ++ (start: nat) (len: nat {start + len <= v n}) ++ : Lemma ( Seq.slice (Spec.Kyber.map' f arr) start (start + len) ++ == Spec.Kyber.map' f (Seq.slice arr start (start + len)) ++ ) ++ = let f_arr = Spec.Kyber.map' f arr in ++ let lhs = Seq.slice f_arr start (start + len) in ++ let rhs = Spec.Kyber.map' f (Seq.slice arr start (start + len)) in ++ introduce forall i. Seq.index lhs i == Seq.index rhs i ++ with ( ++ Seq.lemma_index_slice f_arr start (start + len) i; ++ Seq.lemma_index_slice arr start (start + len) i; ++ let sz_i_start, sz_i = sz (i + start), sz i in ++ assert (Seq.index f_arr (v sz_i_start) == f (Seq.index arr (v (sz_i_start)))); ++ assert (Seq.index rhs (v sz_i) == f (Seq.index (Seq.slice arr start (start + len)) (v sz_i))) ++ ); ++ assert (Seq.equal lhs rhs) ++ ++#push-options "--z3rlimit 2800 --fuel 0 --ifuel 0 --retry 0 --split_queries no" ++let serialize_uncompressed_ring_element re = ++ let serialized: t_Array u8 (sz 384) = Rust_primitives.Hax.repeat 0uy (sz 384) in ++ let max = v (sz 384) * 8 in ++ assert (max == 256 * 12 /\ max == 384 * 8 /\ 128 * 2 * 12 == max); ++ assert (128 == v (length re.f_coefficients /! (sz 2))); ++ let serialized = ++ Rust_primitives.Iterators.foldi_chunks_exact #_ #_ ++ #(fun serialized i -> ++ let i = v i in ++ i <= 128 /\ ( ++ let limit = i * 2 * 12 in ++ let coefficients: t_Array _ (sz 256) = Spec.Kyber.map' to_unsigned_representative re.f_coefficients in ++ bit_vec_sub (bit_vec_of_int_t_array serialized 8 ) 0 limit ++ == bit_vec_sub (bit_vec_of_int_t_array coefficients 12) 0 limit) ++ ) ++ (re.A.f_coefficients <: t_Array _ (sz 256)) ++ (sz 2) + serialized +- (fun serialized temp_1_ -> +- let serialized:t_Array u8 (sz 384) = serialized in +- let i, coefficients:(usize & t_Slice i32) = temp_1_ in +- let coefficient1:u16 = +- Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 0 ] <: i32) +- in +- let coefficient2:u16 = +- Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative (coefficients.[ sz 1 ] <: i32) +- in +- let coef1, coef2, coef3:(u8 & u8 & u8) = +- compress_coefficients_3_ coefficient1 coefficient2 +- in +- let serialized:t_Array u8 (sz 384) = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized +- (sz 3 *! i <: usize) +- coef1 +- in +- let serialized:t_Array u8 (sz 384) = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized +- ((sz 3 *! i <: usize) +! sz 1 <: usize) +- coef2 +- in +- let serialized:t_Array u8 (sz 384) = +- Rust_primitives.Hax.Monomorphized_update_at.update_at_usize serialized +- ((sz 3 *! i <: usize) +! sz 2 <: usize) +- coef3 +- in +- serialized) ++ (fun serialized it -> let i, coefficients = it in + -+let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) -+ : Pure (t_Slice u8 & t_Slice u8) -+ (requires (mid <=. v_SIZE)) -+ (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = -+ Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid ++ let coefficient1 = A.to_unsigned_representative (coefficients.[ sz 0 ] <: i32) in ++ let coefficient2 = A.to_unsigned_representative (coefficients.[ sz 1 ] <: i32) in ++ let (coef1, coef2, coef3) = compress_coefficients_3_ coefficient1 coefficient2 in ++ let j = sz 3 *! i in ++ let serialized' = update3 serialized j coef1 coef2 coef3 in ++ assert ( Seq.slice serialized' (v j) (v j + 3) ++ `Seq.equal` Seq.slice (create3 (coef1, coef2, coef3)) 0 3); ++ bit_vec_equal_intro ++ (let coefficients: t_Array _ (sz 2) = Spec.Kyber.map' to_unsigned_representative coefficients in ++ bit_vec_of_int_t_array coefficients 12) ++ (retype (bit_vec_sub (bit_vec_of_int_t_array serialized' 8) (3 * v i * 8) (3 * 8))); ++ let full_coefficients: t_Array u16 (sz 256) = Spec.Kyber.map' to_unsigned_representative re.f_coefficients in ++ slice_map_lemma #_ #u16 to_unsigned_representative re.f_coefficients (v i * 2) 2; ++ bit_vec_equal_intro ++ (bit_vec_sub (bit_vec_of_int_t_array serialized' 8) 0 (v i * 2 * 12)) ++ (bit_vec_sub (bit_vec_of_int_t_array serialized 8 ) 0 (v i * 2 * 12)); ++ bit_vec_equal_extend (bit_vec_of_int_t_array serialized' 8) ++ (bit_vec_of_int_t_array full_coefficients 12) ++ 0 0 (v i * 2 * 12) (3 * 8); ++ serialized' <: t_Array u8 (sz 384)) + in + serialized ++#pop-options + - type t_MlKemKeyPair (v_PRIVATE_KEY_SIZE: usize) (v_PUBLIC_KEY_SIZE: usize) = { - f_sk:t_MlKemPrivateKey v_PRIVATE_KEY_SIZE; - f_pk:t_MlKemPublicKey v_PUBLIC_KEY_SIZE -@@ -232,7 +247,6 @@ - : t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = - { f_sk = sk; f_pk = pk } <: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE - --/// Creates a new [`MlKemKeyPair`]. - let impl__new - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) - (sk: t_Array u8 v_PRIVATE_KEY_SIZE) -diff -ruN extraction/Libcrux.Kem.Kyber.fst extraction-edited/Libcrux.Kem.Kyber.fst ---- extraction/Libcrux.Kem.Kyber.fst 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.fst 2024-05-07 18:38:45 -@@ -1,12 +1,29 @@ - module Libcrux.Kem.Kyber --#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" +diff -ruN extraction/Libcrux.Kem.Kyber.Serialize.fsti extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti +--- extraction/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-14 15:56:45.414356679 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-14 15:56:45.468355794 +0200 +@@ -2,133 +2,188 @@ + #set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core open FStar.Mul ++open MkSeq ++open BitVecEq --let serialize_kem_secret_key -+let update_at_range_lemma #n -+ (s: t_Slice 't) -+ (i: Core.Ops.Range.t_Range (int_t n) {(Core.Ops.Range.impl_index_range_slice 't n).f_index_pre s i}) -+ (x: t_Slice 't) -+ : Lemma -+ (requires (Seq.length x == v i.f_end - v i.f_start)) -+ (ensures ( -+ let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in -+ let len = v i.f_start in -+ forall (i: nat). i < len ==> Seq.index s i == Seq.index s' i -+ )) -+ [SMTPat (Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x)] -+ = let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in -+ let len = v i.f_start in -+ introduce forall (i:nat {i < len}). Seq.index s i == Seq.index s' i -+ with (assert ( Seq.index (Seq.slice s 0 len) i == Seq.index s i -+ /\ Seq.index (Seq.slice s' 0 len) i == Seq.index s' i )) + val compress_coefficients_10_ (coefficient1 coefficient2 coefficient3 coefficient4: i32) +- : Prims.Pure (u8 & u8 & u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) ++ : Prims.Pure (u8 & u8 & u8 & u8 & u8) ++ (requires True) ++ (ensures fun tuple -> ++ int_t_array_bitwise_eq' ++ (create4 (coefficient1, coefficient2, coefficient3, coefficient4)) 10 ++ (create5 tuple) 8 ++ ) + + val compress_coefficients_11_ + (coefficient1 coefficient2 coefficient3 coefficient4 coefficient5 coefficient6 coefficient7 coefficient8: +- i32) ++ int_t_d i32_inttype 11) + : Prims.Pure (u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8 & u8) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-val compress_coefficients_3_ (coefficient1 coefficient2: u16) +- : Prims.Pure (u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) ++ (requires True) ++ (ensures fun tuple -> ++ int_t_array_bitwise_eq' ++ (create8 (coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8)) 11 ++ (create11 tuple) 8 ++ ) + -+let serialize_kem_secret_key #p - (v_SERIALIZED_KEY_LEN: usize) -- (private_key public_key implicit_rejection_value: t_Slice u8) -- = -+ (private_key public_key implicit_rejection_value: t_Slice u8) = - let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.repeat 0uy v_SERIALIZED_KEY_LEN in - let pointer:usize = sz 0 in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = -@@ -55,6 +72,8 @@ - t_Slice u8) - in - let pointer:usize = pointer +! (Core.Slice.impl__len public_key <: usize) in -+ let h_public_key = (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) -+ <: t_Slice u8) in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out - ({ -@@ -70,16 +89,7 @@ - pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE <: usize - } - <: -- Core.Ops.Range.t_Range usize ] -- <: -- t_Slice u8) -- (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key -- <: -- t_Array u8 (sz 32)) -- <: -- t_Slice u8) -- <: -- t_Slice u8) -+ Core.Ops.Range.t_Range usize ]) h_public_key) - in - let pointer:usize = pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = -@@ -106,14 +116,32 @@ - <: - t_Slice u8) - in -+ assert (Seq.slice out 0 (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) `Seq.equal` private_key); -+ assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) -+ (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) `Seq.equal` public_key); -+ assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -+ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) -+ (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -+ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! -+ Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) -+ `Seq.equal` Libcrux.Kem.Kyber.Hash_functions.v_H public_key); -+ assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -+ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! -+ Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) -+ (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -+ Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! -+ Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE +! -+ Spec.Kyber.v_SHARED_SECRET_SIZE)) -+ == implicit_rejection_value); -+ lemma_slice_append_4 out private_key public_key (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value; - out ++val compress_coefficients_3_ (coefficient1 coefficient2: int_t_d u16_inttype 12) ++ : Prims.Pure (u8 & u8 & u8) ++ (requires True) ++ (ensures fun tuple -> ++ int_t_array_bitwise_eq' ++ (create2 (coefficient1, coefficient2)) 12 ++ (create3 tuple) 8 ++ ) --let decapsulate -+let decapsulate #p - (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: - usize) - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) -- = -+ (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = -+ let orig_secret_key = secret_key.f_value in - let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = - Libcrux.Kem.Kyber.Types.impl_12__split_at v_SECRET_KEY_SIZE secret_key v_CPA_SECRET_KEY_SIZE - in -@@ -123,8 +151,12 @@ - let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at secret_key Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE - in -+ assert (ind_cpa_secret_key == slice orig_secret_key (sz 0) v_CPA_SECRET_KEY_SIZE); -+ assert (ind_cpa_public_key == slice orig_secret_key v_CPA_SECRET_KEY_SIZE (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE)); -+ assert (ind_cpa_public_key_hash == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE) (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)); -+ assert (implicit_rejection_value == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) (length orig_secret_key)); - let decrypted:t_Array u8 (sz 32) = -- Libcrux.Kem.Kyber.Ind_cpa.decrypt v_K -+ Libcrux.Kem.Kyber.Ind_cpa.decrypt #p v_K - v_CIPHERTEXT_SIZE - v_C1_SIZE - v_VECTOR_U_COMPRESSION_FACTOR -@@ -152,6 +184,9 @@ - <: - t_Slice u8) - in -+ lemma_slice_append to_hash decrypted ind_cpa_public_key_hash; -+ assert (decrypted == Spec.Kyber.ind_cpa_decrypt p ind_cpa_secret_key ciphertext.f_value); -+ assert (to_hash == concat decrypted ind_cpa_public_key_hash); - let hashed:t_Array u8 (sz 64) = - Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) - in -@@ -159,6 +194,10 @@ - Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) - Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE - in -+ assert ((shared_secret,pseudorandomness) == split hashed Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE); -+ assert (length implicit_rejection_value = v_SECRET_KEY_SIZE -! v_CPA_SECRET_KEY_SIZE -! v_PUBLIC_KEY_SIZE -! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE); -+ assert (length implicit_rejection_value = Spec.Kyber.v_SHARED_SECRET_SIZE); -+ assert (Spec.Kyber.v_SHARED_SECRET_SIZE <=. Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p); - let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 - v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = - Libcrux.Kem.Kyber.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE -@@ -180,11 +219,14 @@ - <: - t_Slice u8) - in -+ lemma_slice_append to_hash implicit_rejection_value ciphertext.f_value; - let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = - Libcrux.Kem.Kyber.Hash_functions.v_PRF (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) - in -+ assert (implicit_rejection_shared_secret == Spec.Kyber.v_J to_hash); -+ assert (Seq.length ind_cpa_public_key == v v_PUBLIC_KEY_SIZE); - let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE -+ Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE - v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE ind_cpa_public_key decrypted - pseudorandomness -@@ -194,16 +236,18 @@ - (Core.Convert.f_as_ref ciphertext <: t_Slice u8) - (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) - in -+ let res = - Libcrux.Kem.Kyber.Constant_time_ops.select_shared_secret_in_constant_time shared_secret - (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) - selector -+ in -+ res + val compress_coefficients_5_ +- (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: +- u8) +- : Prims.Pure (u8 & u8 & u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) +- +-val decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: i32) +- : Prims.Pure (i32 & i32 & i32 & i32) Prims.l_True (fun _ -> Prims.l_True) ++ (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: int_t_d u8_inttype 5) ++ : Prims.Pure (u8 & u8 & u8 & u8 & u8) ++ (requires True) ++ (ensures fun tuple -> ++ int_t_array_bitwise_eq' ++ (create8 (coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8)) 5 ++ (create5 tuple) 8 ++ ) ++ ++private unfold type i32_d = int_t_d i32_inttype ++val decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: int_t_d i32_inttype 8) ++ : Prims.Pure (i32_d 10 & i32_d 10 & i32_d 10 & i32_d 10) ++ (requires True) ++ (ensures fun (r1, r2, r3, r4) -> ++ int_t_array_bitwise_eq' ++ (create5 (byte1, byte2, byte3, byte4, byte5)) 8 ++ (create4 #i32 (r1, r2, r3, r4)) 10 ++ ) --let encapsulate -+let encapsulate #p - (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) -- (randomness: t_Array u8 (sz 32)) -- = -+ (randomness: t_Array u8 (sz 32)) = - let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = - Libcrux.Kem.Kyber.Ind_cpa.into_padded_array (sz 64) - (Rust_primitives.unsize randomness <: t_Slice u8) -@@ -234,6 +278,10 @@ - <: - t_Slice u8) - in -+ assert (Seq.slice to_hash 0 (v Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) == randomness); -+ lemma_slice_append to_hash randomness (Spec.Kyber.v_H public_key.f_value); -+ assert (to_hash == concat randomness (Spec.Kyber.v_H public_key.f_value)); + val decompress_coefficients_11_ +- (byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11: i32) +- : Prims.Pure (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ (byte2 byte1 byte3 byte5 byte4 byte6 byte7 byte9 byte8 byte10 byte11: int_t_d i32_inttype 8) ++ : Prims.Pure (i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11 & i32_d 11) ++ (requires True) ++ (ensures fun (r1, r2, r3, r4, r5, r6, r7, r8) -> ++ int_t_array_bitwise_eq' ++ (create11 #i32 (byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8, byte9, byte10, byte11)) 8 ++ (create8 #i32 (r1, r2, r3, r4, r5, r6, r7, r8)) 11 ++ ) + + val decompress_coefficients_4_ (byte: u8) +- : Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) +- +-val decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: i32) +- : Prims.Pure (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Prims.Pure (i32_d 4 & i32_d 4) ++ (requires True) ++ (ensures fun (r1, r2) -> ++ int_t_array_bitwise_eq' ++ (create1 byte) 8 ++ (create2 #i32 (r1, r2)) 4 ++ ) + - let hashed:t_Array u8 (sz 64) = - Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) - in -@@ -242,7 +290,7 @@ - Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE - in - let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE -+ Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE - v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN - v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - (Rust_primitives.unsize (Libcrux.Kem.Kyber.Types.impl_18__as_slice v_PUBLIC_KEY_SIZE -@@ -252,32 +300,29 @@ - <: - t_Slice u8) randomness pseudorandomness - in -- let shared_secret_array:t_Array u8 (sz 32) = Rust_primitives.Hax.repeat 0uy (sz 32) in -- let shared_secret_array:t_Array u8 (sz 32) = -- Core.Slice.impl__copy_from_slice shared_secret_array shared_secret -- in -- Core.Convert.f_into ciphertext, shared_secret_array -+ Core.Convert.f_into ciphertext, -+ Core.Result.impl__unwrap (Core.Convert.f_try_into shared_secret -+ <: -+ Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError) - <: - (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) ++val decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: int_t_d i32_inttype 8) ++ : Prims.Pure (i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5) ++ (requires True) ++ (ensures fun (r1, r2, r3, r4, r5, r6, r7, r8) -> ++ int_t_array_bitwise_eq' ++ (create5 #i32 (byte1, byte2, byte3, byte4, byte5)) 8 ++ (create8 #i32 (r1, r2, r3, r4, r5, r6, r7, r8)) 5 ++ ) --let validate_public_key -+#push-options "--z3rlimit 100" -+let validate_public_key #p - (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) - = -- let deserialized_pk:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- Libcrux.Kem.Kyber.Serialize.deserialize_ring_elements_reduced v_PUBLIC_KEY_SIZE -- v_K -+ let pk:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -+ Libcrux.Kem.Kyber.Ind_cpa.deserialize_public_key #p v_K - (public_key.[ { Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } - <: -- Core.Ops.Range.t_RangeTo usize ] -- <: -- t_Slice u8) -+ Core.Ops.Range.t_RangeTo usize ]) - in - let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.serialize_public_key v_K -+ Libcrux.Kem.Kyber.Ind_cpa.serialize_public_key #p v_K - v_RANKED_BYTES_PER_RING_ELEMENT - v_PUBLIC_KEY_SIZE -- deserialized_pk -+ pk - (public_key.[ { Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } - <: - Core.Ops.Range.t_RangeFrom usize ] -@@ -285,109 +330,12 @@ - t_Slice u8) - in - public_key =. public_key_serialized -+#pop-options + val compress_then_serialize_10_ +- (v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (v_OUT_LEN: usize {v v_OUT_LEN >= 320}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) + + val compress_then_serialize_11_ +- (v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (v_OUT_LEN: usize {v v_OUT_LEN >= 352}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) + + val compress_then_serialize_4_ +- (v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (v_OUT_LEN: usize {v v_OUT_LEN >= 128}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) + + val compress_then_serialize_5_ +- (v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (v_OUT_LEN: usize {v v_OUT_LEN >= 160}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) + +-val compress_then_serialize_message (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) ++val compress_then_serialize_message (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ : Pure (t_Array u8 (sz 32)) ++ (requires True) ++ (ensures (fun res -> ++ res == Spec.Kyber.compress_then_encode_message (Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b re))) + + val compress_then_serialize_ring_element_u +- (v_COMPRESSION_FACTOR v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) +- +-val compress_then_serialize_ring_element_v +- (v_COMPRESSION_FACTOR v_OUT_LEN: usize) +- (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ (#p:Spec.Kyber.params) ++ (v_COMPRESSION_FACTOR: usize {v v_COMPRESSION_FACTOR == 10 \/ v v_COMPRESSION_FACTOR == 11}) ++ (v_OUT_LEN: usize { v v_OUT_LEN = 32 * v v_COMPRESSION_FACTOR }) ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ : t_Array u8 v_OUT_LEN ++ ++val compress_then_serialize_ring_element_v (#p:Spec.Kyber.params) ++ (v_COMPRESSION_FACTOR: usize {v_COMPRESSION_FACTOR = sz 4 || v_COMPRESSION_FACTOR = sz 5}) ++ (v_OUT_LEN: usize {v v_OUT_LEN = 32 * v v_COMPRESSION_FACTOR}) ++ (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ : Pure (t_Array u8 v_OUT_LEN) ++ (requires True) ++ (ensures (fun res -> ++ res == ++ Spec.Kyber.compress_then_encode_v p ++ (Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b re))) + +-val deserialize_then_decompress_10_ (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++val deserialize_then_decompress_10_ (serialized: t_Slice u8 {Seq.length serialized == 320}) ++ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + Prims.l_True + (fun _ -> Prims.l_True) + +-val deserialize_then_decompress_11_ (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++val deserialize_then_decompress_11_ (serialized: t_Slice u8 {Seq.length serialized == 352}) ++ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + Prims.l_True + (fun _ -> Prims.l_True) + +-val deserialize_then_decompress_4_ (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++val deserialize_then_decompress_4_ (serialized: t_Slice u8 {Seq.length serialized == 128}) ++ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + Prims.l_True + (fun _ -> Prims.l_True) + +-val deserialize_then_decompress_5_ (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++val deserialize_then_decompress_5_ ++ (serialized: t_Slice u8 {Seq.length serialized == 160}) ++ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement + Prims.l_True + (fun _ -> Prims.l_True) + + val deserialize_then_decompress_message (serialized: t_Array u8 (sz 32)) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires True) ++ (ensures fun res -> ++ Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res == ++ Spec.Kyber.decode_then_decompress_message serialized) + + val deserialize_then_decompress_ring_element_u + (v_COMPRESSION_FACTOR: usize) +- (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) ++ (serialized: t_Slice u8 { ++ match v v_COMPRESSION_FACTOR with ++ | 10 -> Seq.length serialized == 320 ++ | 11 -> Seq.length serialized == 352 ++ | _ -> False ++ }) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires v_COMPRESSION_FACTOR = sz 10 || v_COMPRESSION_FACTOR = sz 11) ++ (ensures fun _ -> True) + +-val deserialize_then_decompress_ring_element_v +- (v_COMPRESSION_FACTOR: usize) ++val deserialize_then_decompress_ring_element_v (#p:Spec.Kyber.params) ++ (v_COMPRESSION_FACTOR: usize {v v_COMPRESSION_FACTOR == 4 \/ v v_COMPRESSION_FACTOR == 5}) + (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// Only use with public values. +-/// This MUST NOT be used with secret inputs, like its caller `deserialize_ring_elements_reduced`. +-val deserialize_to_reduced_ring_element (ring_element: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-/// This function deserializes ring elements and reduces the result by the field +-/// modulus. +-/// This function MUST NOT be used on secret inputs. +-val deserialize_ring_elements_reduced (v_PUBLIC_KEY_SIZE v_K: usize) (public_key: t_Slice u8) +- : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) +- Prims.l_True +- (fun _ -> Prims.l_True) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires (p.v_VECTOR_V_COMPRESSION_FACTOR == v_COMPRESSION_FACTOR /\ ++ length serialized == Spec.Kyber.v_C2_SIZE p)) ++ (ensures fun res -> Libcrux.Kem.Kyber.Arithmetic.to_spec_poly_b res ++ == Spec.Kyber.decode_then_decompress_v p serialized) --let decapsulate_unpacked -- (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: -- usize) -- (state: t_MlKemState v_K) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) -- = -- let (secret_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K):t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- state.f_secret_as_ntt -- in -- let (tt_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K):t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -- state.f_t_as_ntt -- in -- let (a_transpose: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K):t_Array -- (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K = -- state.f_a_transpose -- in -- let (implicit_rejection_value: t_Slice u8):t_Slice u8 = Rust_primitives.unsize state.f_rej in -- let (ind_cpa_public_key_hash: t_Slice u8):t_Slice u8 = -- Rust_primitives.unsize state.f_ind_cpa_public_key_hash -- in -- let decrypted:t_Array u8 (sz 32) = -- Libcrux.Kem.Kyber.Ind_cpa.decrypt_unpacked v_K -- v_CIPHERTEXT_SIZE -- v_C1_SIZE -- v_VECTOR_U_COMPRESSION_FACTOR -- v_VECTOR_V_COMPRESSION_FACTOR -- secret_as_ntt -- ciphertext.Libcrux.Kem.Kyber.Types.f_value -- in -- let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = -- Libcrux.Kem.Kyber.Ind_cpa.into_padded_array (sz 64) -- (Rust_primitives.unsize decrypted <: t_Slice u8) -- in -- let to_hash:t_Array u8 (sz 64) = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from to_hash -- ({ Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE } -- <: -- Core.Ops.Range.t_RangeFrom usize) -- (Core.Slice.impl__copy_from_slice (to_hash.[ { -- Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE -- } -- <: -- Core.Ops.Range.t_RangeFrom usize ] -- <: -- t_Slice u8) -- ind_cpa_public_key_hash -- <: -- t_Slice u8) -- in -- let hashed:t_Array u8 (sz 64) = -- Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) -- in -- let shared_secret, pseudorandomness:(t_Slice u8 & t_Slice u8) = -- Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) -- Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE -- in -- let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 -- v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE -- implicit_rejection_value -- in -- let to_hash:t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = -- Rust_primitives.Hax.Monomorphized_update_at.update_at_range_from to_hash -- ({ Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE } -- <: -- Core.Ops.Range.t_RangeFrom usize) -- (Core.Slice.impl__copy_from_slice (to_hash.[ { -- Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE -- } -- <: -- Core.Ops.Range.t_RangeFrom usize ] -- <: -- t_Slice u8) -- (Core.Convert.f_as_ref ciphertext <: t_Slice u8) -- <: -- t_Slice u8) -- in -- let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = -- Libcrux.Kem.Kyber.Hash_functions.v_PRF (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) -- in -- let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.encrypt_unpacked v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE -- v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR -- v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE tt_as_ntt -- a_transpose decrypted pseudorandomness -- in -- let selector:u8 = -- Libcrux.Kem.Kyber.Constant_time_ops.compare_ciphertexts_in_constant_time v_CIPHERTEXT_SIZE -- (Core.Convert.f_as_ref ciphertext <: t_Slice u8) -- (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) -- in -- Libcrux.Kem.Kyber.Constant_time_ops.select_shared_secret_in_constant_time shared_secret -- (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) -- selector + val deserialize_to_uncompressed_ring_element (serialized: t_Slice u8) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement +- Prims.l_True +- (fun _ -> Prims.l_True) - --let generate_keypair -+let generate_keypair #p - (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) -- (randomness: t_Array u8 (sz 64)) -- = -+ (randomness: t_Array u8 (sz 64)) = - let ind_cpa_keypair_randomness:t_Slice u8 = - randomness.[ { - Core.Ops.Range.f_start = sz 0; -@@ -405,7 +353,7 @@ - in - let ind_cpa_private_key, public_key:(t_Array u8 v_CPA_PRIVATE_KEY_SIZE & - t_Array u8 v_PUBLIC_KEY_SIZE) = -- Libcrux.Kem.Kyber.Ind_cpa.generate_keypair v_K -+ Libcrux.Kem.Kyber.Ind_cpa.generate_keypair #p v_K - v_CPA_PRIVATE_KEY_SIZE - v_PUBLIC_KEY_SIZE - v_BYTES_PER_RING_ELEMENT -@@ -414,7 +362,7 @@ - ind_cpa_keypair_randomness - in - let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = -- serialize_kem_secret_key v_PRIVATE_KEY_SIZE -+ serialize_kem_secret_key #p v_PRIVATE_KEY_SIZE - (Rust_primitives.unsize ind_cpa_private_key <: t_Slice u8) - (Rust_primitives.unsize public_key <: t_Slice u8) - implicit_rejection_value -@@ -428,59 +376,3 @@ - private_key - (Core.Convert.f_into public_key <: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +-val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) +- : Prims.Pure (t_Array u8 (sz 384)) Prims.l_True (fun _ -> Prims.l_True) ++ : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ (requires (length serialized == Spec.Kyber.v_BYTES_PER_RING_ELEMENT)) ++ (ensures fun _ -> True) ++ ++val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) ++ : Pure (t_Array u8 (sz 384)) ++ (requires True) ++ (ensures (fun res -> ++ let coefficients: t_Array _ (sz 256) = Spec.Kyber.map' Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative re.f_coefficients in ++ int_t_array_bitwise_eq res 8 coefficients 12 ++ )) +diff -ruN extraction/Libcrux.Kem.Kyber.Types.fst extraction-edited/Libcrux.Kem.Kyber.Types.fst +--- extraction/Libcrux.Kem.Kyber.Types.fst 2024-05-14 15:56:45.393357024 +0200 ++++ extraction-edited/Libcrux.Kem.Kyber.Types.fst 2024-05-14 15:56:45.464355859 +0200 +@@ -40,13 +40,41 @@ + f_from = fun (value: t_MlKemCiphertext v_SIZE) -> value.f_value + } --let generate_keypair_unpacked -- (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: -- usize) -- (randomness: t_Array u8 (sz 64)) -- = -- let ind_cpa_keypair_randomness:t_Slice u8 = -- randomness.[ { -- Core.Ops.Range.f_start = sz 0; -- Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE -- } -- <: -- Core.Ops.Range.t_Range usize ] -- in -- let implicit_rejection_value:t_Slice u8 = -- randomness.[ { -- Core.Ops.Range.f_start = Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE -- } -- <: -- Core.Ops.Range.t_RangeFrom usize ] -- in -- let (secret_as_ntt, tt_as_ntt, a_transpose), ind_cpa_public_key:((t_Array -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -- t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) & -- t_Array u8 v_PUBLIC_KEY_SIZE) = -- Libcrux.Kem.Kyber.Ind_cpa.generate_keypair_unpacked v_K -- v_PUBLIC_KEY_SIZE -- v_BYTES_PER_RING_ELEMENT -- v_ETA1 -- v_ETA1_RANDOMNESS_SIZE -- ind_cpa_keypair_randomness -- in -- let ind_cpa_public_key_hash:t_Array u8 (sz 32) = -- Libcrux.Kem.Kyber.Hash_functions.v_H (Rust_primitives.unsize ind_cpa_public_key <: t_Slice u8) -- in -- let (rej: t_Array u8 (sz 32)):t_Array u8 (sz 32) = -- Core.Result.impl__unwrap (Core.Convert.f_try_into implicit_rejection_value -- <: -- Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError) -- in -- let (pubkey: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE):Libcrux.Kem.Kyber.Types.t_MlKemPublicKey -- v_PUBLIC_KEY_SIZE = -- Core.Convert.f_from ind_cpa_public_key -- in -- ({ -- f_secret_as_ntt = secret_as_ntt; -- f_t_as_ntt = tt_as_ntt; -- f_a_transpose = a_transpose; -- f_rej = rej; -- f_ind_cpa_public_key_hash = ind_cpa_public_key_hash -- } -- <: -- t_MlKemState v_K), -- pubkey -- <: -- (t_MlKemState v_K & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) -diff -ruN extraction/Libcrux.Kem.Kyber.fsti extraction-edited/Libcrux.Kem.Kyber.fsti ---- extraction/Libcrux.Kem.Kyber.fsti 2024-05-07 18:38:45 -+++ extraction-edited/Libcrux.Kem.Kyber.fsti 2024-05-07 18:38:45 -@@ -6,65 +6,88 @@ - unfold - let t_MlKemSharedSecret = t_Array u8 (sz 32) ++[@@ FStar.Tactics.Typeclasses.tcinstance] ++let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = ++ { ++ f_Error = Core.Array.t_TryFromSliceError; ++ f_try_from_pre = (fun (value: t_Slice u8) -> true); ++ f_try_from_post ++ = ++ (fun ++ (value: t_Slice u8) ++ (out: Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError) ++ -> ++ true); ++ f_try_from ++ = ++ fun (value: t_Slice u8) -> ++ match Core.Convert.f_try_into value with ++ | Core.Result.Result_Ok value -> ++ Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) ++ <: ++ Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError ++ | Core.Result.Result_Err e -> ++ Core.Result.Result_Err e ++ <: ++ Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError ++ } ++ + let impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : t_Array u8 v_SIZE = + self.f_value --/// Seed size for key generation - let v_KEY_GENERATION_SEED_SIZE: usize = - Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +! - Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + let impl_6__len (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : usize = v_SIZE + + let impl_6__split_at (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) (mid: usize) +- : (t_Slice u8 & t_Slice u8) = ++ : Pure (t_Slice u8 & t_Slice u8) ++ (requires (mid <=. v_SIZE)) ++ (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = + Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid + + type t_MlKemPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } +@@ -86,15 +114,53 @@ + f_from = fun (value: t_MlKemPrivateKey v_SIZE) -> value.f_value + } --/// Serialize the secret key. --val serialize_kem_secret_key -+val serialize_kem_secret_key (#p:Spec.Kyber.params) - (v_SERIALIZED_KEY_LEN: usize) - (private_key public_key implicit_rejection_value: t_Slice u8) -- : Prims.Pure (t_Array u8 v_SERIALIZED_KEY_LEN) Prims.l_True (fun _ -> Prims.l_True) -+ : Pure (t_Array u8 v_SERIALIZED_KEY_LEN) -+ (requires (length private_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -+ length public_key == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ length implicit_rejection_value == Spec.Kyber.v_SHARED_SECRET_SIZE /\ -+ v_SERIALIZED_KEY_LEN == Spec.Kyber.v_SECRET_KEY_SIZE p)) -+ (ensures (fun res -> res == -+ Seq.append private_key ( -+ Seq.append public_key ( -+ Seq.append (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value)))) ++[@@ FStar.Tactics.Typeclasses.tcinstance] ++let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = ++ { ++ f_Error = Core.Array.t_TryFromSliceError; ++ f_try_from_pre = (fun (value: t_Slice u8) -> true); ++ f_try_from_post ++ = ++ (fun ++ (value: t_Slice u8) ++ (out: Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError) ++ -> ++ true); ++ f_try_from ++ = ++ fun (value: t_Slice u8) -> ++ match Core.Convert.f_try_into value with ++ | Core.Result.Result_Ok value -> ++ Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) ++ <: ++ Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError ++ | Core.Result.Result_Err e -> ++ Core.Result.Result_Err e ++ <: ++ Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError ++ } ++ + let impl_12__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : t_Array u8 v_SIZE = + self.f_value --val decapsulate -+val decapsulate (#p:Spec.Kyber.params) - (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: - usize) - (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) - (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -+ : Pure (t_Array u8 (sz 32)) -+ (requires ( p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ -+ Spec.Kyber.valid_params p /\ -+ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -+ v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ -+ v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p /\ -+ v_SECRET_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ -+ v_CPA_SECRET_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -+ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -+ v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ -+ v_C1_BLOCK_SIZE == Spec.Kyber.v_C1_BLOCK_SIZE p /\ -+ v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ -+ v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p -+ )) -+ (ensures (fun res -> -+ res == Spec.Kyber.ind_cca_decapsulate p secret_key.f_value ciphertext.f_value)) + let impl_12__len (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : usize = v_SIZE --val encapsulate -+val encapsulate (#p:Spec.Kyber.params) - (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) - (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) - (randomness: t_Array u8 (sz 32)) -- : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) -+ (requires (p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ -+ Spec.Kyber.valid_params p /\ -+ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -+ v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ -+ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -+ v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ -+ v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ -+ v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p /\ -+ v_VECTOR_U_BLOCK_LEN == Spec.Kyber.v_C1_BLOCK_SIZE p -+ )) + let impl_12__split_at (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) (mid: usize) +- : (t_Slice u8 & t_Slice u8) = ++ : Pure (t_Slice u8 & t_Slice u8) ++ (requires (mid <=. v_SIZE)) ++ (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = + Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid --val validate_public_key -+ (ensures (fun (ct,ss) -> -+ (ct.f_value,ss) == Spec.Kyber.ind_cca_encapsulate p public_key.f_value randomness)) + -+val validate_public_key (#p:Spec.Kyber.params) - (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) - (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) -- : Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) -+ : Prims.Pure bool -+ (requires (v_K == p.v_RANK /\ -+ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p -+ )) -+ (ensures (fun _ -> Prims.l_True)) ++ ++ ++ ++ ++ ++ ++ ++ ++ + type t_MlKemPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } --type t_MlKemState (v_K: usize) = { -- f_secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K; -- f_t_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K; -- f_a_transpose:t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K; -- f_rej:t_Array u8 (sz 32); -- f_ind_cpa_public_key_hash:t_Array u8 (sz 32) --} + [@@ FStar.Tactics.Typeclasses.tcinstance] +@@ -132,67 +198,6 @@ + f_from = fun (value: t_MlKemPublicKey v_SIZE) -> value.f_value + } + +-let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : t_Array u8 v_SIZE = +- self.f_value - --val decapsulate_unpacked -- (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: -- usize) -- (state: t_MlKemState v_K) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +-let impl_18__len (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : usize = v_SIZE - --val generate_keypair -+val generate_keypair (#p:Spec.Kyber.params) - (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) - (randomness: t_Array u8 (sz 64)) -- : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -- Prims.l_True -- (fun _ -> Prims.l_True) +-let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) +- : (t_Slice u8 & t_Slice u8) = +- Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid - --val generate_keypair_unpacked -- (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: -- usize) -- (randomness: t_Array u8 (sz 64)) -- : Prims.Pure (t_MlKemState v_K & Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) -- Prims.l_True -- (fun _ -> Prims.l_True) -+ : Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -+ (requires (v_K == p.v_RANK /\ v_ETA1 == p.v_ETA1 /\ -+ v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -+ v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -+ v_CPA_PRIVATE_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -+ v_PRIVATE_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ -+ v_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p -+ )) -+ (ensures (fun kp -> -+ (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.ind_cca_generate_keypair p randomness)) -diff -ruN extraction/Libcrux.Kem.fst extraction-edited/Libcrux.Kem.fst ---- extraction/Libcrux.Kem.fst 1970-01-01 01:00:00 -+++ extraction-edited/Libcrux.Kem.fst 2024-05-07 18:38:45 -@@ -0,0 +1,6 @@ -+module Libcrux.Kem -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+open Core -+open FStar.Mul +-[@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = +- { +- f_Error = Core.Array.t_TryFromSliceError; +- f_try_from_pre = (fun (value: t_Slice u8) -> true); +- f_try_from_post +- = +- (fun +- (value: t_Slice u8) +- (out: Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError) +- -> +- true); +- f_try_from +- = +- fun (value: t_Slice u8) -> +- match Core.Convert.f_try_into value with +- | Core.Result.Result_Ok value -> +- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) +- <: +- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError +- | Core.Result.Result_Err e -> +- Core.Result.Result_Err e +- <: +- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError +- } +- +-[@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = +- { +- f_Error = Core.Array.t_TryFromSliceError; +- f_try_from_pre = (fun (value: t_Slice u8) -> true); +- f_try_from_post +- = +- (fun +- (value: t_Slice u8) +- (out: Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError) +- -> +- true); +- f_try_from +- = +- fun (value: t_Slice u8) -> +- match Core.Convert.f_try_into value with +- | Core.Result.Result_Ok value -> +- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) +- <: +- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError +- | Core.Result.Result_Err e -> +- Core.Result.Result_Err e +- <: +- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError +- } +- + [@@ FStar.Tactics.Typeclasses.tcinstance] + let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) (t_Slice u8) = + { +@@ -219,7 +224,17 @@ + Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError + } + +-/// An ML-KEM key pair ++let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : t_Array u8 v_SIZE = ++ self.f_value ++ ++let impl_18__len (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : usize = v_SIZE + ++let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) ++ : Pure (t_Slice u8 & t_Slice u8) ++ (requires (mid <=. v_SIZE)) ++ (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = ++ Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid + + type t_MlKemKeyPair (v_PRIVATE_KEY_SIZE: usize) (v_PUBLIC_KEY_SIZE: usize) = { + f_sk:t_MlKemPrivateKey v_PRIVATE_KEY_SIZE; + f_pk:t_MlKemPublicKey v_PUBLIC_KEY_SIZE +@@ -232,7 +247,6 @@ + : t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = + { f_sk = sk; f_pk = pk } <: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE + +-/// Creates a new [`MlKemKeyPair`]. + let impl__new + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) + (sk: t_Array u8 v_PRIVATE_KEY_SIZE) diff -ruN extraction/Libcrux_platform.Platform.fsti extraction-edited/Libcrux_platform.Platform.fsti ---- extraction/Libcrux_platform.Platform.fsti 1970-01-01 01:00:00 -+++ extraction-edited/Libcrux_platform.Platform.fsti 2024-05-07 18:38:45 +--- extraction/Libcrux_platform.Platform.fsti 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-edited/Libcrux_platform.Platform.fsti 2024-05-14 15:56:45.421356565 +0200 @@ -0,0 +1,20 @@ +module Libcrux_platform.Platform +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -9135,8 +9165,8 @@ diff -ruN extraction/Libcrux_platform.Platform.fsti extraction-edited/Libcrux_pl + +val simd128_support: Prims.unit -> Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) diff -ruN extraction/MkSeq.fst extraction-edited/MkSeq.fst ---- extraction/MkSeq.fst 1970-01-01 01:00:00 -+++ extraction-edited/MkSeq.fst 2024-05-07 18:38:45 +--- extraction/MkSeq.fst 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-edited/MkSeq.fst 2024-05-14 15:56:45.438356286 +0200 @@ -0,0 +1,91 @@ +module MkSeq +open Core @@ -9230,8 +9260,8 @@ diff -ruN extraction/MkSeq.fst extraction-edited/MkSeq.fst + +%splice[] (init 13 (fun i -> create_gen_tac (i + 1))) diff -ruN extraction/Spec.Kyber.fst extraction-edited/Spec.Kyber.fst ---- extraction/Spec.Kyber.fst 1970-01-01 01:00:00 -+++ extraction-edited/Spec.Kyber.fst 2024-05-07 18:38:45 +--- extraction/Spec.Kyber.fst 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-edited/Spec.Kyber.fst 2024-05-14 15:56:45.430356417 +0200 @@ -0,0 +1,435 @@ +module Spec.Kyber +#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" diff --git a/proofs/fstar/extraction-secret-independent.patch b/proofs/fstar/extraction-secret-independent.patch index aa8a29e84..6f69b4599 100644 --- a/proofs/fstar/extraction-secret-independent.patch +++ b/proofs/fstar/extraction-secret-independent.patch @@ -1,6 +1,6 @@ diff -ruN extraction-edited/BitVecEq.fst extraction-secret-independent/BitVecEq.fst ---- extraction-edited/BitVecEq.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/BitVecEq.fst 1970-01-01 01:00:00 +--- extraction-edited/BitVecEq.fst 2024-05-14 15:56:45.444356187 +0200 ++++ extraction-secret-independent/BitVecEq.fst 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -module BitVecEq - @@ -15,8 +15,8 @@ diff -ruN extraction-edited/BitVecEq.fst extraction-secret-independent/BitVecEq. - - diff -ruN extraction-edited/BitVecEq.fsti extraction-secret-independent/BitVecEq.fsti ---- extraction-edited/BitVecEq.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/BitVecEq.fsti 1970-01-01 01:00:00 +--- extraction-edited/BitVecEq.fsti 2024-05-14 15:56:45.440356253 +0200 ++++ extraction-secret-independent/BitVecEq.fsti 1970-01-01 01:00:00.000000000 +0100 @@ -1,294 +0,0 @@ -module BitVecEq -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -313,8 +313,8 @@ diff -ruN extraction-edited/BitVecEq.fsti extraction-secret-independent/BitVecEq - = admit () -*) diff -ruN extraction-edited/Libcrux.Digest.fsti extraction-secret-independent/Libcrux.Digest.fsti ---- extraction-edited/Libcrux.Digest.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Digest.fsti 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Digest.fsti 2024-05-14 15:56:45.433356368 +0200 ++++ extraction-secret-independent/Libcrux.Digest.fsti 2024-05-14 15:56:45.473355711 +0200 @@ -1,31 +1,41 @@ module Libcrux.Digest #set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -326,6 +326,28 @@ diff -ruN extraction-edited/Libcrux.Digest.fsti extraction-secret-independent/Li - : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) - Prims.l_True - (fun _ -> Prims.l_True) +- +-val sha3_256_ (payload: t_Slice u8) +- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) +- +-val sha3_512_ (payload: t_Slice u8) +- : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) +- +-val shake128 (v_LEN: usize) (data: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) +- +-val shake256 (v_LEN: usize) (data: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) +- +-val shake128x4_portable (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) +- Prims.l_True +- (fun _ -> Prims.l_True) +- +-val shake128x4 (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) +- Prims.l_True +- (fun _ -> Prims.l_True) +type t_Algorithm = + | Algorithm_Sha1 : t_Algorithm + | Algorithm_Sha224 : t_Algorithm @@ -338,9 +360,7 @@ diff -ruN extraction-edited/Libcrux.Digest.fsti extraction-secret-independent/Li + | Algorithm_Sha3_256_ : t_Algorithm + | Algorithm_Sha3_384_ : t_Algorithm + | Algorithm_Sha3_512_ : t_Algorithm - --val sha3_256_ (payload: t_Slice u8) -- : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) ++ +let digest_size (mode: t_Algorithm) : usize = + match mode with + | Algorithm_Sha1 -> sz 20 @@ -354,33 +374,19 @@ diff -ruN extraction-edited/Libcrux.Digest.fsti extraction-secret-independent/Li + | Algorithm_Sha3_256_ -> sz 32 + | Algorithm_Sha3_384_ -> sz 48 + | Algorithm_Sha3_512_ -> sz 64 - --val sha3_512_ (payload: t_Slice u8) -- : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) ++ +val sha3_256_ (payload: t_Slice u8) : t_Array u8 (sz 32) - --val shake128 (v_LEN: usize) (data: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ +val sha3_512_ (payload: t_Slice u8) : t_Array u8 (sz 64) - --val shake256 (v_LEN: usize) (data: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ +val shake128 (v_LEN: usize) (data: t_Slice u8) : t_Array u8 v_LEN - --val shake128x4_portable (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) -- Prims.l_True -- (fun _ -> Prims.l_True) ++ +val shake128x4 (v_LEN: usize) (data0: t_Slice u8) (data1: t_Slice u8) (data2: t_Slice u8) (data3: t_Slice u8): (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) - --val shake128x4 (v_LEN: usize) (data0 data1 data2 data3: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN & t_Array u8 v_LEN) -- Prims.l_True -- (fun _ -> Prims.l_True) ++ +val shake256 (v_LEN: usize) (data: t_Slice u8) : t_Array u8 v_LEN diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst extraction-secret-independent/Libcrux.Kem.Kyber.Arithmetic.fst ---- extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-14 15:56:45.434356351 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Arithmetic.fst 2024-05-14 15:56:45.512355072 +0200 @@ -1,364 +1,81 @@ module Libcrux.Kem.Kyber.Arithmetic -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" @@ -622,20 +628,20 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst extraction-secret-i - }; - res -#pop-options +- +-let montgomery_multiply_sfe_by_fer fe fer = +- montgomery_reduce (mul_i32_b fe fer) + let c:i32 = k_times_modulus >>! v_MONTGOMERY_SHIFT in + let value_high:i32 = value >>! v_MONTGOMERY_SHIFT in + value_high -! c --let montgomery_multiply_sfe_by_fer fe fer = -- montgomery_reduce (mul_i32_b fe fer) +let montgomery_multiply_sfe_by_fer (fe fer: i32) = montgomery_reduce (fe *! fer <: i32) +-let to_standard_domain mfe = +- montgomery_reduce (mul_i32_b mfe (v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS <: i32_b 1353)) +let to_standard_domain (mfe: i32) = + montgomery_reduce (mfe *! v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS <: i32) --let to_standard_domain mfe = -- montgomery_reduce (mul_i32_b mfe (v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS <: i32_b 1353)) -- -let to_unsigned_representative fe = +let to_unsigned_representative (fe: i32) = let _:Prims.unit = () <: Prims.unit in @@ -653,10 +659,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst extraction-secret-i - assert (v fe < 0 ==> v res == v fe + 3329); - assert (v fe >= 0 ==> v res == v fe); - res <: int_t_d u16_inttype 12 -+ cast (fe +! (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS &. (fe >>! 31l <: i32) <: i32) <: i32) -+ <: -+ u16 - +- -let derefine_poly_b #b x = - let r = createi (sz 256) (fun i -> (x.f_coefficients.[i] <: i32)) in - {f_coefficients = r} @@ -668,7 +671,10 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst extraction-secret-i -let derefine_matrix_b #v_K #b x = - let r = createi v_K (fun i -> derefine_vector_b #v_K #b x.[i]) in - r -- ++ cast (fe +! (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS &. (fe >>! 31l <: i32) <: i32) <: i32) ++ <: ++ u16 + -let cast_poly_b #b1 #b2 x = - let r = createi (sz 256) (fun i -> (x.f_coefficients.[i] <: i32_b b2)) in - let res = {f_coefficients = r} in @@ -785,8 +791,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fst extraction-secret-i - - diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Arithmetic.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-14 15:56:45.458355957 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Arithmetic.fsti 2024-05-14 15:56:45.509355121 +0200 @@ -3,32 +3,10 @@ open Core open FStar.Mul @@ -835,13 +841,13 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- let v_MONTGOMERY_R_SQUARED_MOD_FIELD_MODULUS: i32 = 1353l -let v_MONTGOMERY_SHIFT: u8 = 16uy +- +-val v_MONTGOMERY_R: x:i32{v x = pow2 16 /\ x = 65536l} +let v_MONTGOMERY_SHIFT: pub_u8 = 16uy --val v_MONTGOMERY_R: x:i32{v x = pow2 16 /\ x = 65536l} +-val v_MONTGOMERY_R_INV: x:i32{v x >= 0 /\ v x < 3329 /\ (v x * v v_MONTGOMERY_R) % 3329 == 1 /\ x = 169l} +let v_MONTGOMERY_R: i32 = 1l <= 0 /\ v x < 3329 /\ (v x * v v_MONTGOMERY_R) % 3329 == 1 /\ x = 169l} -- -let int_to_spec_fe (m:int) : Spec.Kyber.field_element = - let m_v = m % v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS in - assert (m_v > - v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS); @@ -872,21 +878,11 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- fun result -> let result:u32 = result in - v result = v value % pow2 (v n)) -+ v result < v (Core.Num.impl__u32__pow 2ul (Core.Convert.f_into n <: u32) <: u32)) - +- -//let barrett_pre (value:i32) = -// v value <= v v_BARRETT_R /\ v value >= - v v_BARRETT_R -// Appears to work up to +/- 2^28, but not at +/- 2^29 -+val barrett_reduce (value: i32) -+ : Prims.Pure i32 -+ (requires -+ v (Core.Convert.f_from value <: i64) > v (Core.Ops.Arith.Neg.neg v_BARRETT_R <: i64) && -+ v (Core.Convert.f_from value <: i64) < v v_BARRETT_R) -+ (ensures -+ fun result -> -+ let result:i32 = result in -+ v result > v (Core.Ops.Arith.Neg.neg Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) && -+ v result < v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS) ++ v result < v (Core.Num.impl__u32__pow 2ul (Core.Convert.f_into n <: u32) <: u32)) -let barrett_post (value:i32) (result:i32) = - v result % v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS = @@ -905,29 +901,18 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- -val montgomery_reduce #b (value: i32_b b) - : Prims.Pure (i32_b (nat_div_ceil b (v v_MONTGOMERY_R) + 1665)) - (requires True) -+val montgomery_reduce (value: i32) ++val barrett_reduce (value: i32) + : Prims.Pure i32 + (requires -+ v value >= -+ v ((Core.Ops.Arith.Neg.neg Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) *! -+ v_MONTGOMERY_R -+ <: -+ i32) && -+ v value <= v (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS *! v_MONTGOMERY_R <: i32)) ++ v (Core.Convert.f_from value <: i64) > v (Core.Ops.Arith.Neg.neg v_BARRETT_R <: i64) && ++ v (Core.Convert.f_from value <: i64) < v v_BARRETT_R) (ensures fun result -> let result:i32 = result in - montgomery_post value result) -+ v result >= -+ v ((Core.Ops.Arith.Neg.neg (3l *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) <: i32 -+ ) /! -+ 2l -+ <: -+ i32) && -+ v result <= v ((3l *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) /! 2l <: i32)) - -+val montgomery_multiply_sfe_by_fer (fe fer: i32) -+ : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) +- ++ v result > v (Core.Ops.Arith.Neg.neg Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) && ++ v result < v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS) -val montgomery_multiply_sfe_by_fer #b1 #b2 (fe:i32_b b1) (fer: i32_b b2) - : Pure (i32_b (nat_div_ceil (b1 * b2) (v v_MONTGOMERY_R) + 1665)) @@ -935,8 +920,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- - (ensures (fun result -> - montgomery_post (mul_i32_b fe fer) (result))) - -+val to_standard_domain (mfe: i32) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) - +- -val to_standard_domain #b (mfe: i32_b b) - : Pure (i32_b (nat_div_ceil (b * 1353) (v v_MONTGOMERY_R) + 1665)) - (requires (b * 1353 < pow2_31)) @@ -947,6 +931,31 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- -val to_unsigned_representative (fe: wfFieldElement) - : Prims.Pure (int_t_d u16_inttype 12) - (requires True) ++val montgomery_reduce (value: i32) ++ : Prims.Pure i32 ++ (requires ++ v value >= ++ v ((Core.Ops.Arith.Neg.neg Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) *! ++ v_MONTGOMERY_R ++ <: ++ i32) && ++ v value <= v (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS *! v_MONTGOMERY_R <: i32)) ++ (ensures ++ fun result -> ++ let result:i32 = result in ++ v result >= ++ v ((Core.Ops.Arith.Neg.neg (3l *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) <: i32 ++ ) /! ++ 2l ++ <: ++ i32) && ++ v result <= v ((3l *! Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) /! 2l <: i32)) ++ ++val montgomery_multiply_sfe_by_fer (fe fer: i32) ++ : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) ++ ++val to_standard_domain (mfe: i32) : Prims.Pure i32 Prims.l_True (fun _ -> Prims.l_True) ++ +val to_unsigned_representative (fe: i32) + : Prims.Pure u16 + (requires @@ -958,16 +967,11 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- - v result == to_spec_fe fe /\ - result >=. 0us && - result <. (cast (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) <: u16)) -+ v result >= v 0us && -+ v result < v (cast (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) <: u16)) - +- -type t_PolynomialRingElement = { f_coefficients:t_Array (t_FieldElement) (sz 256) } -+type t_PolynomialRingElement = { f_coefficients:t_Array i32 (sz 256) } - +- -type t_PolynomialRingElement_b b = { f_coefficients:t_Array (i32_b b) (sz 256) } -+let impl__PolynomialRingElement__ZERO: t_PolynomialRingElement = -+ { f_coefficients = Rust_primitives.Hax.repeat 0l (sz 256) } <: t_PolynomialRingElement - +- -type wfPolynomialRingElement = t_PolynomialRingElement_b (v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS - 1) - -val derefine_poly_b (#b1:nat) (x:t_PolynomialRingElement_b b1): @@ -1089,9 +1093,14 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- - (ensures fun result -> - (forall i. v result.f_coefficients.[i] == v lhs.f_coefficients.[i] + v rhs.f_coefficients.[i])) - -- -- -- ++ v result >= v 0us && ++ v result < v (cast (Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32) <: u16)) + ++type t_PolynomialRingElement = { f_coefficients:t_Array i32 (sz 256) } + ++let impl__PolynomialRingElement__ZERO: t_PolynomialRingElement = ++ { f_coefficients = Rust_primitives.Hax.repeat 0l (sz 256) } <: t_PolynomialRingElement + +val add_to_ring_element (v_K: usize) (lhs rhs: t_PolynomialRingElement) + : Prims.Pure t_PolynomialRingElement + (requires @@ -1140,8 +1149,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Arithmetic.fsti extraction-secret- + <: + bool)) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Compress.fst extraction-secret-independent/Libcrux.Kem.Kyber.Compress.fst ---- extraction-edited/Libcrux.Kem.Kyber.Compress.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Compress.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Compress.fst 2024-05-14 15:56:45.448356122 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Compress.fst 2024-05-14 15:56:45.489355449 +0200 @@ -1,79 +1,39 @@ module Libcrux.Kem.Kyber.Compress -#set-options "--fuel 0 --ifuel 0 --z3rlimit 200" @@ -1150,27 +1159,12 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Compress.fst extraction-secret-ind open FStar.Mul -let compress_message_coefficient fe = -+let compress_ciphertext_coefficient (coefficient_bits: pub_u8) (fe: u16) = -+ let _:Prims.unit = () <: Prims.unit in -+ let _:Prims.unit = () <: Prims.unit in -+ let compressed:u64 = (cast (fe <: u16) <: u64) <>! 35l in -+ cast (Libcrux.Kem.Kyber.Arithmetic.get_n_least_significant_bits coefficient_bits -+ (cast (compressed <: u64) <: u32) -+ <: -+ u32) -+ <: -+ i32 -+ -+let compress_message_coefficient (fe: u16) = - let (shifted: i16):i16 = 1664s -! (cast (fe <: u16) <: i16) in +- let (shifted: i16):i16 = 1664s -! (cast (fe <: u16) <: i16) in - assert (v shifted == 1664 - v fe); - let mask:i16 = shifted >>! 15l in +- let mask:i16 = shifted >>! 15l in - assert (v mask = v shifted / pow2 15); - assert (if v shifted < 0 then mask = ones else mask = zero); - let shifted_to_positive:i16 = mask ^. shifted in +- let shifted_to_positive:i16 = mask ^. shifted in - logxor_lemma shifted mask; - assert (v shifted < 0 ==> v shifted_to_positive = v (lognot shifted)); - neg_equiv_lemma shifted; @@ -1180,7 +1174,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Compress.fst extraction-secret-ind - assert (v shifted >= 0 ==> mask ^. shifted = shifted); - assert (v shifted >= 0 ==> v shifted_to_positive = v shifted); - assert (shifted_to_positive >=. 0s); - let shifted_positive_in_range:i16 = shifted_to_positive -! 832s in +- let shifted_positive_in_range:i16 = shifted_to_positive -! 832s in - assert (1664 - v fe >= 0 ==> v shifted_positive_in_range == 832 - v fe); - assert (1664 - v fe < 0 ==> v shifted_positive_in_range == -2497 + v fe); - let r0 = shifted_positive_in_range >>! 15l in @@ -1195,10 +1189,9 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Compress.fst extraction-secret-ind - assert (v fe > 2496 ==> r1 = 0s); - assert (v res = v r1); - res -+ cast ((shifted_positive_in_range >>! 15l <: i16) &. 1s <: i16) <: u8 - +- -let compress_ciphertext_coefficient coefficient_bits fe = -+let decompress_ciphertext_coefficient (coefficient_bits: pub_u8) (fe: i32) = ++let compress_ciphertext_coefficient (coefficient_bits: pub_u8) (fe: u16) = let _:Prims.unit = () <: Prims.unit in let _:Prims.unit = () <: Prims.unit in - let compressed:u32 = (cast (fe <: u16) <: u32) <>! 35l in ++ cast (Libcrux.Kem.Kyber.Arithmetic.get_n_least_significant_bits coefficient_bits ++ (cast (compressed <: u64) <: u32) ++ <: ++ u32) + <: + i32 - in - res -- + -#push-options "--z3rlimit 300" -let decompress_ciphertext_coefficient coefficient_bits fe = -- let _:Prims.unit = () <: Prims.unit in -- let _:Prims.unit = () <: Prims.unit in ++let compress_message_coefficient (fe: u16) = ++ let (shifted: i16):i16 = 1664s -! (cast (fe <: u16) <: i16) in ++ let mask:i16 = shifted >>! 15l in ++ let shifted_to_positive:i16 = mask ^. shifted in ++ let shifted_positive_in_range:i16 = shifted_to_positive -! 832s in ++ cast ((shifted_positive_in_range >>! 15l <: i16) &. 1s <: i16) <: u8 ++ ++let decompress_ciphertext_coefficient (coefficient_bits: pub_u8) (fe: i32) = + let _:Prims.unit = () <: Prims.unit in + let _:Prims.unit = () <: Prims.unit in - assert (v (1ul <= v 0l && -+ v fe < v (Core.Num.impl__i32__pow 2l (cast (coefficient_bits <: u8) <: u32) <: i32)) - (ensures - fun result -> - let result:i32 = result in +- (ensures +- fun result -> +- let result:i32 = result in - result >=. 0l && - result <. (Core.Num.impl__i32__pow 2l (cast (coefficient_bits <: u8) <: u32) <: i32)) -+ v result < v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS) - +- -open Rust_primitives.Integers - -val decompress_ciphertext_coefficient @@ -1308,19 +1314,22 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Compress.fsti extraction-secret-in - (fe: int_t_d i32_inttype (v coefficient_bits)) - : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.i32_b (v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS - 1)) - (requires True) -- (ensures -- fun result -> -- let result:i32 = result in ++ v fe >= v 0l && ++ v fe < v (Core.Num.impl__i32__pow 2l (cast (coefficient_bits <: u8) <: u32) <: i32)) + (ensures + fun result -> + let result:i32 = result in - result <. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS) -- ++ v result < v Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS) + val decompress_message_coefficient (fe: i32) - : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfFieldElement - (requires fe =. 0l || fe =. 1l) - (fun result -> v result >= 0 /\ v result < 3329) + : Prims.Pure i32 (requires fe =. 0l || fe =. 1l) (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst extraction-secret-independent/Libcrux.Kem.Kyber.Constant_time_ops.fst ---- extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-14 15:56:45.441356237 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Constant_time_ops.fst 2024-05-14 15:56:45.516355006 +0200 @@ -4,163 +4,61 @@ open FStar.Mul @@ -1509,8 +1518,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fst extraction-s -#pop-options + out diff -ruN extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Constant_time_ops.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-14 15:56:45.447356138 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Constant_time_ops.fsti 2024-05-14 15:56:45.507355154 +0200 @@ -20,26 +20,30 @@ val compare_ciphertexts_in_constant_time (v_CIPHERTEXT_SIZE: usize) (lhs rhs: t_Slice u8) @@ -1553,8 +1562,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Constant_time_ops.fsti extraction- + let _:Prims.unit = temp_0_ in + result = rhs <: bool)) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Conversions.fst extraction-secret-independent/Libcrux.Kem.Kyber.Conversions.fst ---- extraction-edited/Libcrux.Kem.Kyber.Conversions.fst 1970-01-01 01:00:00 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Conversions.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Conversions.fst 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Conversions.fst 2024-05-14 15:56:45.475355679 +0200 @@ -0,0 +1,87 @@ +module Libcrux.Kem.Kyber.Conversions +#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -1643,234 +1652,626 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Conversions.fst extraction-secret- + +let to_unsigned_representative (fe: i32) : u16 = + cast (fe +! ((fe >>! 15l <: i32) &. Libcrux.Kem.Kyber.Constants.v_FIELD_MODULUS <: i32)) <: u16 -\ No newline at end of file -diff -ruN extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fst ---- extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-07 18:38:45 -@@ -3,28 +3,18 @@ +\ Pas de fin de ligne à la fin du fichier +diff -ruN extraction-edited/Libcrux.Kem.Kyber.fst extraction-secret-independent/Libcrux.Kem.Kyber.fst +--- extraction-edited/Libcrux.Kem.Kyber.fst 2024-05-14 15:56:45.465355843 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.fst 2024-05-14 15:56:45.504355203 +0200 +@@ -1,29 +1,12 @@ + module Libcrux.Kem.Kyber +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core open FStar.Mul --let v_G (input: t_Slice u8) = -- let res = Libcrux.Digest.sha3_512_ input in -- admit(); // We assume that sha3_512 correctly implements G -- res -+let v_G (input: t_Slice u8) = Libcrux.Digest.sha3_512_ input - --let v_H (input: t_Slice u8) = -- let res = Libcrux.Digest.sha3_256_ input in -- admit(); // We assume that sha3_512 correctly implements H -- res -+let v_H (input: t_Slice u8) = Libcrux.Digest.sha3_256_ input - --let v_PRF (v_LEN: usize) (input: t_Slice u8) = -- let res = Libcrux.Digest.shake256 v_LEN input in -- admit(); // We assume that sha3_512 correctly implements H -- res -+let v_PRF (v_LEN: usize) (input: t_Slice u8) = Libcrux.Digest.shake256 v_LEN input - --let v_XOFx4 v_K (input: t_Array (t_Array u8 (sz 34)) v_K) = -- assert (v v_K >= 2); -+let v_XOFx4 (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) = - let out:t_Array (t_Array u8 (sz 840)) v_K = - Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 840) <: t_Array u8 (sz 840)) v_K - in - let out:t_Array (t_Array u8 (sz 840)) v_K = -- if ~.(Libcrux_platform.Platform.simd256_support () <: bool) -+ if ~.(Libcrux_platform.simd256_support () <: bool) || ~.true - then - Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; -@@ -48,7 +38,7 @@ - t_Array (t_Array u8 (sz 840)) v_K) - else - let out:t_Array (t_Array u8 (sz 840)) v_K = -- match cast (v_K <: usize) <: u8 with -+ match cast (v_K <: usize) <: pub_u8 with - | 2uy -> - let d0, d1, _, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & - t_Array u8 (sz 840)) = -@@ -66,7 +56,6 @@ - in - out - | 3uy -> -- assert (v (cast v_K <: u8) = 3); - let d0, d1, d2, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & - t_Array u8 (sz 840)) = - Libcrux.Digest.shake128x4 (sz 840) -@@ -86,7 +75,6 @@ - in - out - | 4uy -> -- assert (v (cast v_K <: u8) = 4); - let d0, d1, d2, d3:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & - t_Array u8 (sz 840)) = - Libcrux.Digest.shake128x4 (sz 840) -@@ -112,5 +100,4 @@ - in - out - in -- admit(); // We assume that shake128x4 correctly implements XOFx4 -- out -+ out -diff -ruN extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-07 18:38:45 -@@ -3,17 +3,12 @@ - open Core - open FStar.Mul - --val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True -- (ensures (fun res -> res == Spec.Kyber.v_G input)) -+val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) - --val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True -- (ensures (fun res -> res == Spec.Kyber.v_H input)) -+val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) - - val v_PRF (v_LEN: usize) (input: t_Slice u8) -- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True -- (ensures (fun res -> res == Spec.Kyber.v_PRF v_LEN input)) -- --val v_XOFx4 (v_K: usize{v v_K >= 2 /\ v v_K <= 4}) (input: t_Array (t_Array u8 (sz 34)) v_K) -- : Prims.Pure (t_Array (t_Array u8 (sz 840)) v_K) Prims.l_True -- (ensures (fun res -> -- (forall i. i < v v_K ==> Seq.index res i == Spec.Kyber.v_XOF (sz 840) (Seq.index input i)))) -+ : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) -+ -+val v_XOFx4 (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) -+ : Prims.Pure (t_Array (t_Array u8 (sz 840)) v_K) Prims.l_True (fun _ -> Prims.l_True) -diff -ruN extraction-edited/Libcrux.Kem.Kyber.Helper.fst extraction-secret-independent/Libcrux.Kem.Kyber.Helper.fst ---- extraction-edited/Libcrux.Kem.Kyber.Helper.fst 1970-01-01 01:00:00 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Helper.fst 2024-05-07 18:38:46 -@@ -0,0 +1,6 @@ -+module Libcrux.Kem.Kyber.Helper -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+open Core -+open FStar.Mul -+ -+ -diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fst ---- extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-07 18:38:46 -@@ -1,5 +1,5 @@ - module Libcrux.Kem.Kyber.Ind_cpa --#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" - open Core - open FStar.Mul - -@@ -37,37 +37,33 @@ - in - out - --unfold let acc_t (v_K v_ETA:usize) = (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1)) v_K) --unfold let inv_t v_K v_ETA = acc_t v_K v_ETA -> usize -> Type -- --let wfZero: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = -- (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) -- --let etaZero (v_ETA:usize{v v_ETA >= 1 /\ v v_ETA < pow2 31}): Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA) = -- (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #(v v_ETA) Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) +-let update_at_range_lemma #n +- (s: t_Slice 't) +- (i: Core.Ops.Range.t_Range (int_t n) {(Core.Ops.Range.impl_index_range_slice 't n).f_index_pre s i}) +- (x: t_Slice 't) +- : Lemma +- (requires (Seq.length x == v i.f_end - v i.f_start)) +- (ensures ( +- let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in +- let len = v i.f_start in +- forall (i: nat). i < len ==> Seq.index s i == Seq.index s' i +- )) +- [SMTPat (Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x)] +- = let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in +- let len = v i.f_start in +- introduce forall (i:nat {i < len}). Seq.index s i == Seq.index s' i +- with (assert ( Seq.index (Seq.slice s 0 len) i == Seq.index s i +- /\ Seq.index (Seq.slice s' 0 len) i == Seq.index s' i )) - --let sample_vector_cbd (#p:Spec.Kyber.params) -+let sample_ring_element_cbd - (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) -- (prf_input: t_Array u8 (sz 33)) domain_separator = -- let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = -- Rust_primitives.Hax.repeat (etaZero (sz (pow2 (v v_ETA2) - 1))) v_K -+ (prf_input: t_Array u8 (sz 33)) -+ (domain_separator: u8) +-let serialize_kem_secret_key #p ++let serialize_kem_secret_key + (v_SERIALIZED_KEY_LEN: usize) +- (private_key public_key implicit_rejection_value: t_Slice u8) = ++ (private_key public_key implicit_rejection_value: t_Slice u8) + = -+ let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K + let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.repeat 0uy v_SERIALIZED_KEY_LEN in + let pointer:usize = sz 0 in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = +@@ -72,8 +55,6 @@ + t_Slice u8) in -- let orig_domain_separator = domain_separator in -- [@ inline_let] -- let inv : inv_t v_K v_ETA2 = fun (acc:acc_t v_K v_ETA2) (i:usize) -> -- let (domain_separator,prf_input,error_1_) = acc in -- if (i >=. sz 0 && i <=. v_K) -- then -- domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) -- else true in -- let (domain_separator, prf_input, error_1_):acc_t v_K (v_ETA2) = -- Rust_primitives.Iterators.foldi_range #_ #(acc_t v_K (v_ETA2)) #inv { -+ let domain_separator, error_1_, prf_input:(u8 & -+ t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -+ t_Array u8 (sz 33)) = -+ Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = v_K - } -- (domain_separator, prf_input, error_1_) + let pointer:usize = pointer +! (Core.Slice.impl__len public_key <: usize) in +- let h_public_key = (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) +- <: t_Slice u8) in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = + Rust_primitives.Hax.Monomorphized_update_at.update_at_range out + ({ +@@ -89,7 +70,16 @@ + pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE <: usize + } + <: +- Core.Ops.Range.t_Range usize ]) h_public_key) ++ Core.Ops.Range.t_Range usize ] + <: -+ Core.Ops.Range.t_Range usize) -+ <: -+ Core.Ops.Range.t_Range usize) -+ (domain_separator, error_1_, prf_input ++ t_Slice u8) ++ (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key ++ <: ++ t_Array u8 (sz 32)) ++ <: ++ t_Slice u8) + <: -+ (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array u8 (sz 33)) -+ ) - (fun temp_0_ i -> -- let domain_separator, prf_input, error_1_:acc_t v_K (v_ETA2) = -+ let domain_separator, error_1_, prf_input:(u8 & -+ t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -+ t_Array u8 (sz 33)) = - temp_0_ - in - let i:usize = i in -@@ -81,46 +77,49 @@ - Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE - (Rust_primitives.unsize prf_input <: t_Slice u8) - in -- let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = -+ let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = - Rust_primitives.Hax.Monomorphized_update_at.update_at_usize error_1_ - i -- (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA2 -+ (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA2 - (Rust_primitives.unsize prf_output <: t_Slice u8) - <: -- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) - in -- domain_separator, prf_input, error_1_) -+ domain_separator, error_1_, prf_input -+ <: -+ (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & -+ t_Array u8 (sz 33))) ++ t_Slice u8) in -- let hax_temp_output:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = error_1_ in -- admit(); //P-F -+ let hax_temp_output:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = error_1_ in - prf_input, domain_separator, hax_temp_output - <: -- (t_Array u8 (sz 33) & u8 & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA2)) v_K) -+ (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + let pointer:usize = pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE in + let out:t_Array u8 v_SERIALIZED_KEY_LEN = +@@ -116,32 +106,14 @@ + <: + t_Slice u8) + in +- assert (Seq.slice out 0 (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) `Seq.equal` private_key); +- assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) +- (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) `Seq.equal` public_key); +- assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! +- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) +- (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! +- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! +- Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) +- `Seq.equal` Libcrux.Kem.Kyber.Hash_functions.v_H public_key); +- assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! +- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! +- Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) +- (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! +- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! +- Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE +! +- Spec.Kyber.v_SHARED_SECRET_SIZE)) +- == implicit_rejection_value); +- lemma_slice_append_4 out private_key public_key (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value; + out --#push-options "--split_queries no --z3rlimit 300" --let sample_vector_cbd_then_ntt (#p:Spec.Kyber.params) -+let sample_vector_cbd_then_ntt - (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) -- (prf_input: t_Array u8 (sz 33)) domain_separator = -- let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -- Rust_primitives.Hax.repeat (wfZero) v_K -+ (prf_input: t_Array u8 (sz 33)) -+ (domain_separator: u8) +-let decapsulate #p ++let decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) +- (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = +- let orig_secret_key = secret_key.f_value in ++ (secret_key: Libcrux.Kem.Kyber.Types.t_KyberPrivateKey v_SECRET_KEY_SIZE) ++ (ciphertext: Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE) + = -+ let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K + let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = + Libcrux.Kem.Kyber.Types.impl_12__split_at v_SECRET_KEY_SIZE secret_key v_CPA_SECRET_KEY_SIZE in -- let orig_domain_separator = domain_separator in -- [@ inline_let] -- let inv: (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K) -> usize -> Type = fun acc i -> -- let (domain_separator,prf_input,re_as_ntt) = acc in -- if (i >=. sz 0 && i <=. v_K) -- then +@@ -151,12 +123,8 @@ + let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at secret_key Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE + in +- assert (ind_cpa_secret_key == slice orig_secret_key (sz 0) v_CPA_SECRET_KEY_SIZE); +- assert (ind_cpa_public_key == slice orig_secret_key v_CPA_SECRET_KEY_SIZE (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE)); +- assert (ind_cpa_public_key_hash == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE) (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)); +- assert (implicit_rejection_value == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) (length orig_secret_key)); + let decrypted:t_Array u8 (sz 32) = +- Libcrux.Kem.Kyber.Ind_cpa.decrypt #p v_K ++ Libcrux.Kem.Kyber.Ind_cpa.decrypt v_K + v_CIPHERTEXT_SIZE + v_C1_SIZE + v_VECTOR_U_COMPRESSION_FACTOR +@@ -184,9 +152,6 @@ + <: + t_Slice u8) + in +- lemma_slice_append to_hash decrypted ind_cpa_public_key_hash; +- assert (decrypted == Spec.Kyber.ind_cpa_decrypt p ind_cpa_secret_key ciphertext.f_value); +- assert (to_hash == concat decrypted ind_cpa_public_key_hash); + let hashed:t_Array u8 (sz 64) = + Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) + in +@@ -194,10 +159,6 @@ + Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) + Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + in +- assert ((shared_secret,pseudorandomness) == split hashed Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE); +- assert (length implicit_rejection_value = v_SECRET_KEY_SIZE -! v_CPA_SECRET_KEY_SIZE -! v_PUBLIC_KEY_SIZE -! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE); +- assert (length implicit_rejection_value = Spec.Kyber.v_SHARED_SECRET_SIZE); +- assert (Spec.Kyber.v_SHARED_SECRET_SIZE <=. Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p); + let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 + v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = + Libcrux.Kem.Kyber.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE +@@ -219,14 +180,11 @@ + <: + t_Slice u8) + in +- lemma_slice_append to_hash implicit_rejection_value ciphertext.f_value; + let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = + Libcrux.Kem.Kyber.Hash_functions.v_PRF (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) + in +- assert (implicit_rejection_shared_secret == Spec.Kyber.v_J to_hash); +- assert (Seq.length ind_cpa_public_key == v v_PUBLIC_KEY_SIZE); + let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE ++ Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 + v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE ind_cpa_public_key decrypted + pseudorandomness +@@ -236,18 +194,16 @@ + (Core.Convert.f_as_ref ciphertext <: t_Slice u8) + (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) + in +- let res = + Libcrux.Kem.Kyber.Constant_time_ops.select_shared_secret_in_constant_time shared_secret + (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) + selector +- in +- res + +-let encapsulate #p ++let encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) +- (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +- (randomness: t_Array u8 (sz 32)) = ++ (public_key: Libcrux.Kem.Kyber.Types.t_KyberPublicKey v_PUBLIC_KEY_SIZE) ++ (randomness: t_Array u8 (sz 32)) ++ = + let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = + Libcrux.Kem.Kyber.Ind_cpa.into_padded_array (sz 64) + (Rust_primitives.unsize randomness <: t_Slice u8) +@@ -278,10 +234,6 @@ + <: + t_Slice u8) + in +- assert (Seq.slice to_hash 0 (v Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) == randomness); +- lemma_slice_append to_hash randomness (Spec.Kyber.v_H public_key.f_value); +- assert (to_hash == concat randomness (Spec.Kyber.v_H public_key.f_value)); +- + let hashed:t_Array u8 (sz 64) = + Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) + in +@@ -290,7 +242,7 @@ + Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + in + let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE ++ Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE + v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN + v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE + (Rust_primitives.unsize (Libcrux.Kem.Kyber.Types.impl_18__as_slice v_PUBLIC_KEY_SIZE +@@ -300,42 +252,23 @@ + <: + t_Slice u8) randomness pseudorandomness + in +- Core.Convert.f_into ciphertext, +- Core.Result.impl__unwrap (Core.Convert.f_try_into shared_secret +- <: +- Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError) +- <: +- (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) +- +-#push-options "--z3rlimit 100" +-let validate_public_key #p +- (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) +- (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) +- = +- let pk:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = +- Libcrux.Kem.Kyber.Ind_cpa.deserialize_public_key #p v_K +- (public_key.[ { Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } ++ let shared_secret:t_Array u8 (sz 32) = ++ match Core.Convert.f_try_into shared_secret with ++ | Core.Result.Result_Ok shared_secret -> shared_secret ++ | Core.Result.Result_Err _ -> ++ Rust_primitives.Hax.never_to_any (Core.Panicking.panic "explicit panic" + <: +- Core.Ops.Range.t_RangeTo usize ]) ++ Rust_primitives.Hax.t_Never) + in +- let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = +- Libcrux.Kem.Kyber.Ind_cpa.serialize_public_key #p v_K +- v_RANKED_BYTES_PER_RING_ELEMENT +- v_PUBLIC_KEY_SIZE +- pk +- (public_key.[ { Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } +- <: +- Core.Ops.Range.t_RangeFrom usize ] +- <: +- t_Slice u8) +- in +- public_key =. public_key_serialized +-#pop-options ++ Core.Convert.f_into ciphertext, shared_secret ++ <: ++ (Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) + +-let generate_keypair #p ++let generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) +- (randomness: t_Array u8 (sz 64)) = ++ (randomness: t_Array u8 (sz 64)) ++ = + let ind_cpa_keypair_randomness:t_Slice u8 = + randomness.[ { + Core.Ops.Range.f_start = sz 0; +@@ -353,7 +286,7 @@ + in + let ind_cpa_private_key, public_key:(t_Array u8 v_CPA_PRIVATE_KEY_SIZE & + t_Array u8 v_PUBLIC_KEY_SIZE) = +- Libcrux.Kem.Kyber.Ind_cpa.generate_keypair #p v_K ++ Libcrux.Kem.Kyber.Ind_cpa.generate_keypair v_K + v_CPA_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + v_BYTES_PER_RING_ELEMENT +@@ -362,17 +295,16 @@ + ind_cpa_keypair_randomness + in + let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = +- serialize_kem_secret_key #p v_PRIVATE_KEY_SIZE ++ serialize_kem_secret_key v_PRIVATE_KEY_SIZE + (Rust_primitives.unsize ind_cpa_private_key <: t_Slice u8) + (Rust_primitives.unsize public_key <: t_Slice u8) + implicit_rejection_value + in +- let (private_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE):Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey ++ let (private_key: Libcrux.Kem.Kyber.Types.t_KyberPrivateKey v_PRIVATE_KEY_SIZE):Libcrux.Kem.Kyber.Types.t_KyberPrivateKey + v_PRIVATE_KEY_SIZE = + Core.Convert.f_from secret_key_serialized + in + Libcrux.Kem.Kyber.Types.impl__from v_PRIVATE_KEY_SIZE + v_PUBLIC_KEY_SIZE + private_key +- (Core.Convert.f_into public_key <: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +- ++ (Core.Convert.f_into public_key <: Libcrux.Kem.Kyber.Types.t_KyberPublicKey v_PUBLIC_KEY_SIZE) +diff -ruN extraction-edited/Libcrux.Kem.Kyber.fsti extraction-secret-independent/Libcrux.Kem.Kyber.fsti +--- extraction-edited/Libcrux.Kem.Kyber.fsti 2024-05-14 15:56:45.443356204 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.fsti 2024-05-14 15:56:45.518354973 +0200 +@@ -4,90 +4,37 @@ + open FStar.Mul + + unfold +-let t_MlKemSharedSecret = t_Array u8 (sz 32) ++let t_KyberSharedSecret = t_Array u8 (sz 32) + + let v_KEY_GENERATION_SEED_SIZE: usize = + Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +! + Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + +-val serialize_kem_secret_key (#p:Spec.Kyber.params) ++val serialize_kem_secret_key + (v_SERIALIZED_KEY_LEN: usize) + (private_key public_key implicit_rejection_value: t_Slice u8) +- : Pure (t_Array u8 v_SERIALIZED_KEY_LEN) +- (requires (length private_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ +- length public_key == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ +- length implicit_rejection_value == Spec.Kyber.v_SHARED_SECRET_SIZE /\ +- v_SERIALIZED_KEY_LEN == Spec.Kyber.v_SECRET_KEY_SIZE p)) +- (ensures (fun res -> res == +- Seq.append private_key ( +- Seq.append public_key ( +- Seq.append (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value)))) ++ : Prims.Pure (t_Array u8 v_SERIALIZED_KEY_LEN) Prims.l_True (fun _ -> Prims.l_True) + +-val decapsulate (#p:Spec.Kyber.params) ++val decapsulate + (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: + usize) +- (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) +- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) +- : Pure (t_Array u8 (sz 32)) +- (requires ( p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ +- Spec.Kyber.valid_params p /\ +- v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ +- v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ +- v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p /\ +- v_SECRET_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ +- v_CPA_SECRET_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ +- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ +- v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ +- v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ +- v_C1_BLOCK_SIZE == Spec.Kyber.v_C1_BLOCK_SIZE p /\ +- v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ +- v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p +- )) +- (ensures (fun res -> +- res == Spec.Kyber.ind_cca_decapsulate p secret_key.f_value ciphertext.f_value)) ++ (secret_key: Libcrux.Kem.Kyber.Types.t_KyberPrivateKey v_SECRET_KEY_SIZE) ++ (ciphertext: Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE) ++ : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + +-val encapsulate (#p:Spec.Kyber.params) ++val encapsulate + (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) +- (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) ++ (public_key: Libcrux.Kem.Kyber.Types.t_KyberPublicKey v_PUBLIC_KEY_SIZE) + (randomness: t_Array u8 (sz 32)) +- : Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) +- (requires (p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ +- Spec.Kyber.valid_params p /\ +- v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ +- v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ +- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ +- v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ +- v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ +- v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ +- v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p /\ +- v_VECTOR_U_BLOCK_LEN == Spec.Kyber.v_C1_BLOCK_SIZE p +- )) +- +- (ensures (fun (ct,ss) -> +- (ct.f_value,ss) == Spec.Kyber.ind_cca_encapsulate p public_key.f_value randomness)) +- +-val validate_public_key (#p:Spec.Kyber.params) +- (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) +- (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) +- : Prims.Pure bool +- (requires (v_K == p.v_RANK /\ +- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ +- v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p +- )) +- (ensures (fun _ -> Prims.l_True)) ++ : Prims.Pure (Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) ++ Prims.l_True ++ (fun _ -> Prims.l_True) + +-val generate_keypair (#p:Spec.Kyber.params) ++val generate_keypair + (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: + usize) + (randomness: t_Array u8 (sz 64)) +- : Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) +- (requires (v_K == p.v_RANK /\ v_ETA1 == p.v_ETA1 /\ +- v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ +- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ +- v_CPA_PRIVATE_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ +- v_PRIVATE_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ +- v_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p +- )) +- (ensures (fun kp -> +- (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.ind_cca_generate_keypair p randomness)) ++ : Prims.Pure (Libcrux.Kem.Kyber.Types.t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) ++ Prims.l_True ++ (fun _ -> Prims.l_True) +diff -ruN extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fst +--- extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-14 15:56:45.450356089 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fst 2024-05-14 15:56:45.479355613 +0200 +@@ -3,28 +3,18 @@ + open Core + open FStar.Mul + +-let v_G (input: t_Slice u8) = +- let res = Libcrux.Digest.sha3_512_ input in +- admit(); // We assume that sha3_512 correctly implements G +- res ++let v_G (input: t_Slice u8) = Libcrux.Digest.sha3_512_ input + +-let v_H (input: t_Slice u8) = +- let res = Libcrux.Digest.sha3_256_ input in +- admit(); // We assume that sha3_512 correctly implements H +- res ++let v_H (input: t_Slice u8) = Libcrux.Digest.sha3_256_ input + +-let v_PRF (v_LEN: usize) (input: t_Slice u8) = +- let res = Libcrux.Digest.shake256 v_LEN input in +- admit(); // We assume that sha3_512 correctly implements H +- res ++let v_PRF (v_LEN: usize) (input: t_Slice u8) = Libcrux.Digest.shake256 v_LEN input + +-let v_XOFx4 v_K (input: t_Array (t_Array u8 (sz 34)) v_K) = +- assert (v v_K >= 2); ++let v_XOFx4 (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) = + let out:t_Array (t_Array u8 (sz 840)) v_K = + Rust_primitives.Hax.repeat (Rust_primitives.Hax.repeat 0uy (sz 840) <: t_Array u8 (sz 840)) v_K + in + let out:t_Array (t_Array u8 (sz 840)) v_K = +- if ~.(Libcrux_platform.Platform.simd256_support () <: bool) ++ if ~.(Libcrux_platform.simd256_support () <: bool) || ~.true + then + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; +@@ -48,7 +38,7 @@ + t_Array (t_Array u8 (sz 840)) v_K) + else + let out:t_Array (t_Array u8 (sz 840)) v_K = +- match cast (v_K <: usize) <: u8 with ++ match cast (v_K <: usize) <: pub_u8 with + | 2uy -> + let d0, d1, _, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) = +@@ -66,7 +56,6 @@ + in + out + | 3uy -> +- assert (v (cast v_K <: u8) = 3); + let d0, d1, d2, _:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) = + Libcrux.Digest.shake128x4 (sz 840) +@@ -86,7 +75,6 @@ + in + out + | 4uy -> +- assert (v (cast v_K <: u8) = 4); + let d0, d1, d2, d3:(t_Array u8 (sz 840) & t_Array u8 (sz 840) & t_Array u8 (sz 840) & + t_Array u8 (sz 840)) = + Libcrux.Digest.shake128x4 (sz 840) +@@ -112,5 +100,4 @@ + in + out + in +- admit(); // We assume that shake128x4 correctly implements XOFx4 +- out ++ out +diff -ruN extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fsti +--- extraction-edited/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-14 15:56:45.453356039 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Hash_functions.fsti 2024-05-14 15:56:45.487355482 +0200 +@@ -3,17 +3,12 @@ + open Core + open FStar.Mul + +-val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True +- (ensures (fun res -> res == Spec.Kyber.v_G input)) ++val v_G (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 64)) Prims.l_True (fun _ -> Prims.l_True) + +-val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True +- (ensures (fun res -> res == Spec.Kyber.v_H input)) ++val v_H (input: t_Slice u8) : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + + val v_PRF (v_LEN: usize) (input: t_Slice u8) +- : Prims.Pure (t_Array u8 v_LEN) Prims.l_True +- (ensures (fun res -> res == Spec.Kyber.v_PRF v_LEN input)) +- +-val v_XOFx4 (v_K: usize{v v_K >= 2 /\ v v_K <= 4}) (input: t_Array (t_Array u8 (sz 34)) v_K) +- : Prims.Pure (t_Array (t_Array u8 (sz 840)) v_K) Prims.l_True +- (ensures (fun res -> +- (forall i. i < v v_K ==> Seq.index res i == Spec.Kyber.v_XOF (sz 840) (Seq.index input i)))) ++ : Prims.Pure (t_Array u8 v_LEN) Prims.l_True (fun _ -> Prims.l_True) ++ ++val v_XOFx4 (v_K: usize) (input: t_Array (t_Array u8 (sz 34)) v_K) ++ : Prims.Pure (t_Array (t_Array u8 (sz 840)) v_K) Prims.l_True (fun _ -> Prims.l_True) +diff -ruN extraction-edited/Libcrux.Kem.Kyber.Helper.fst extraction-secret-independent/Libcrux.Kem.Kyber.Helper.fst +--- extraction-edited/Libcrux.Kem.Kyber.Helper.fst 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Helper.fst 2024-05-14 15:56:45.497355318 +0200 +@@ -0,0 +1,6 @@ ++module Libcrux.Kem.Kyber.Helper ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++open Core ++open FStar.Mul ++ ++ +diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fst +--- extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-14 15:56:45.460355925 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fst 2024-05-14 15:56:45.491355416 +0200 +@@ -1,5 +1,5 @@ + module Libcrux.Kem.Kyber.Ind_cpa +-#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" + open Core + open FStar.Mul + +@@ -37,37 +37,33 @@ + in + out + +-unfold let acc_t (v_K v_ETA:usize) = (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA) - 1)) v_K) +-unfold let inv_t v_K v_ETA = acc_t v_K v_ETA -> usize -> Type +- +-let wfZero: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement = +- (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) +- +-let etaZero (v_ETA:usize{v v_ETA >= 1 /\ v v_ETA < pow2 31}): Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA) = +- (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #(v v_ETA) Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) +- +-let sample_vector_cbd (#p:Spec.Kyber.params) ++let sample_ring_element_cbd + (v_K v_ETA2_RANDOMNESS_SIZE v_ETA2: usize) +- (prf_input: t_Array u8 (sz 33)) domain_separator = +- let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = +- Rust_primitives.Hax.repeat (etaZero (sz (pow2 (v v_ETA2) - 1))) v_K +- in +- let orig_domain_separator = domain_separator in +- [@ inline_let] +- let inv : inv_t v_K v_ETA2 = fun (acc:acc_t v_K v_ETA2) (i:usize) -> +- let (domain_separator,prf_input,error_1_) = acc in +- if (i >=. sz 0 && i <=. v_K) +- then +- domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) +- else true in +- let (domain_separator, prf_input, error_1_):acc_t v_K (v_ETA2) = +- Rust_primitives.Iterators.foldi_range #_ #(acc_t v_K (v_ETA2)) #inv { ++ (prf_input: t_Array u8 (sz 33)) ++ (domain_separator: u8) ++ = ++ let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in ++ let domain_separator, error_1_, prf_input:(u8 & ++ t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & ++ t_Array u8 (sz 33)) = ++ Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end = v_K + } +- (domain_separator, prf_input, error_1_) ++ <: ++ Core.Ops.Range.t_Range usize) ++ <: ++ Core.Ops.Range.t_Range usize) ++ (domain_separator, error_1_, prf_input ++ <: ++ (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & t_Array u8 (sz 33)) ++ ) + (fun temp_0_ i -> +- let domain_separator, prf_input, error_1_:acc_t v_K (v_ETA2) = ++ let domain_separator, error_1_, prf_input:(u8 & ++ t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & ++ t_Array u8 (sz 33)) = + temp_0_ + in + let i:usize = i in +@@ -81,46 +77,49 @@ + Libcrux.Kem.Kyber.Hash_functions.v_PRF v_ETA2_RANDOMNESS_SIZE + (Rust_primitives.unsize prf_input <: t_Slice u8) + in +- let error_1_:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = ++ let error_1_:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = + Rust_primitives.Hax.Monomorphized_update_at.update_at_usize error_1_ + i +- (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution #p v_ETA2 ++ (Libcrux.Kem.Kyber.Sampling.sample_from_binomial_distribution v_ETA2 + (Rust_primitives.unsize prf_output <: t_Slice u8) + <: +- Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) + in +- domain_separator, prf_input, error_1_) ++ domain_separator, error_1_, prf_input ++ <: ++ (u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & ++ t_Array u8 (sz 33))) + in +- let hax_temp_output:t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (pow2 (v v_ETA2) - 1)) v_K = error_1_ in +- admit(); //P-F ++ let hax_temp_output:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = error_1_ in + prf_input, domain_separator, hax_temp_output + <: +- (t_Array u8 (sz 33) & u8 & t_Array (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_ETA2)) v_K) ++ (t_Array u8 (sz 33) & u8 & t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + +-#push-options "--split_queries no --z3rlimit 300" +-let sample_vector_cbd_then_ntt (#p:Spec.Kyber.params) ++let sample_vector_cbd_then_ntt + (v_K v_ETA v_ETA_RANDOMNESS_SIZE: usize) +- (prf_input: t_Array u8 (sz 33)) domain_separator = +- let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = +- Rust_primitives.Hax.repeat (wfZero) v_K +- in +- let orig_domain_separator = domain_separator in +- [@ inline_let] +- let inv: (u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K) -> usize -> Type = fun acc i -> +- let (domain_separator,prf_input,re_as_ntt) = acc in +- if (i >=. sz 0 && i <=. v_K) +- then - domain_separator = orig_domain_separator +! (mk_int #u8_inttype (v i)) - else true in - let (domain_separator, prf_input, re_as_ntt):(u8 & t_Array u8 (sz 33) & t_Array (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) v_K)= - Rust_primitives.Iterators.foldi_range #_ #_ #inv { ++ (prf_input: t_Array u8 (sz 33)) ++ (domain_separator: u8) ++ = ++ let re_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in + let domain_separator, prf_input, re_as_ntt:(u8 & t_Array u8 (sz 33) & + t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ @@ -1924,9 +2325,9 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde re_as_ntt, domain_separator <: - (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K & u8) +- + (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K & u8) -- -let compress_then_serialize_u #p v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN input = +let compress_then_serialize_u + (v_K v_OUT_LEN v_COMPRESSION_FACTOR v_BLOCK_LEN: usize) @@ -2010,13 +2411,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) = - let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Hax.repeat wfZero v_K -+let deserialize_then_decompress_u -+ (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) -+ (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) -+ = -+ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K - in +- in - let acc_t1 = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in - [@ inline_let] - let inv = fun (acc:acc_t1) (i:usize) -> True in @@ -2024,6 +2419,13 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - { Core.Ops.Range.f_end = v_VECTOR_U_ENCODED_SIZE } <: Core.Ops.Range.t_RangeTo usize ] in - assert (length sl == v_VECTOR_U_ENCODED_SIZE); - let chunk_len = ((Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT *! ++let deserialize_then_decompress_u ++ (v_K v_CIPHERTEXT_SIZE v_U_COMPRESSION_FACTOR: usize) ++ (ciphertext: t_Array u8 v_CIPHERTEXT_SIZE) ++ = ++ let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in + let u_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate + (Core.Slice.impl__chunks_exact (Rust_primitives.unsize ciphertext <: t_Slice u8) @@ -2084,10 +2486,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - (v_K: usize) (public_key: t_Slice u8) = - let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Hax.repeat wfZero v_K -+let deserialize_public_key (v_K: usize) (public_key: t_Slice u8) = -+ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K - in +- in - let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in - [@ inline_let] - let inv = fun (acc:acc_t) (i:usize) -> True in @@ -2096,6 +2495,10 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv - public_key - chunk_len ++let deserialize_public_key (v_K: usize) (public_key: t_Slice u8) = ++ let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in + let tt_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate + (Core.Slice.impl__chunks_exact public_key @@ -2127,16 +2530,12 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - admit(); //P-F - tt_as_ntt -#pop-options -+ tt_as_ntt - +- -#push-options "--split_queries always" -let deserialize_secret_key (#p:Spec.Kyber.params) (v_K: usize) (secret_key: t_Slice u8) = - let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Hax.repeat wfZero v_K -+let deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) = -+ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K - in +- in - let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in - [@ inline_let] - let inv = fun (acc:acc_t) (i:usize) -> True in @@ -2149,6 +2548,12 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - Rust_primitives.Iterators.foldi_chunks_exact #u8 #acc_t #inv - sl - chunk_len ++ tt_as_ntt ++ ++let deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) = ++ let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in + let secret_as_ntt:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate + (Core.Slice.impl__chunks_exact secret_key @@ -2222,12 +2627,13 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - let res = Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message in - res -#pop-options -+ Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message - +- -#push-options "--z3rlimit 200" -let encrypt #p - v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - public_key ++ Libcrux.Kem.Kyber.Serialize.compress_then_serialize_message message ++ +let encrypt + (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: + usize) @@ -2460,8 +2866,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fst extraction-secret-inde - res - diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-14 15:56:45.469355777 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Ind_cpa.fsti 2024-05-14 15:56:45.514355039 +0200 @@ -1,151 +1,80 @@ module Libcrux.Kem.Kyber.Ind_cpa -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" @@ -2537,10 +2943,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-secret-ind - (ensures fun res -> - Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res == - Spec.Kyber.(vector_ntt (decode_then_decompress_u p (Seq.slice ciphertext 0 (v (Spec.Kyber.v_C1_SIZE p)))))) -+ : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ Prims.l_True -+ (fun _ -> Prims.l_True) - +- -val deserialize_public_key (#p:Spec.Kyber.params) - (v_K: usize) (public_key: t_Array u8 (Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p)) - : Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) @@ -2558,17 +2961,21 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-secret-ind - Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res == - Spec.Kyber.vector_decode_12 #p secret_key) - ++ : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ +val deserialize_public_key (v_K: usize) (public_key: t_Slice u8) + : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + Prims.l_True + (fun _ -> Prims.l_True) - --val decrypt (#p:Spec.Kyber.params) ++ +val deserialize_secret_key (v_K: usize) (secret_key: t_Slice u8) + : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + Prims.l_True + (fun _ -> Prims.l_True) -+ + +-val decrypt (#p:Spec.Kyber.params) +val decrypt (v_K v_CIPHERTEXT_SIZE v_VECTOR_U_ENCODED_SIZE v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR: usize) @@ -2583,9 +2990,9 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-secret-ind - v_V_COMPRESSION_FACTOR == p.v_VECTOR_V_COMPRESSION_FACTOR)) - (ensures (fun res -> - res == Spec.Kyber.ind_cpa_decrypt p secret_key ciphertext)) +- + : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) -- -val encrypt (#p:Spec.Kyber.params) +val encrypt (v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_LEN v_C2_LEN v_U_COMPRESSION_FACTOR v_V_COMPRESSION_FACTOR v_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: @@ -2662,8 +3069,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ind_cpa.fsti extraction-secret-ind + Prims.l_True + (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst extraction-secret-independent/Libcrux.Kem.Kyber.Kyber1024.fst ---- extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-14 15:56:45.457355974 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber1024.fst 2024-05-14 15:56:45.501355252 +0200 @@ -3,37 +3,22 @@ open Core open FStar.Mul @@ -2712,8 +3119,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fst extraction-secret-in (sz 3168) (sz 1568) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Kyber1024.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-14 15:56:45.437356302 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber1024.fsti 2024-05-14 15:56:45.511355088 +0200 @@ -63,32 +63,27 @@ Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE +! v_CPA_PKE_CIPHERTEXT_SIZE_1024_ @@ -2759,8 +3166,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber1024.fsti extraction-secret-i Prims.l_True (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst extraction-secret-independent/Libcrux.Kem.Kyber.Kyber512.fst ---- extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-14 15:56:45.422356548 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber512.fst 2024-05-14 15:56:45.486355498 +0200 @@ -3,37 +3,22 @@ open Core open FStar.Mul @@ -2809,8 +3216,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber512.fst extraction-secret-ind (sz 1632) (sz 800) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Kyber512.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-14 15:56:45.456355990 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber512.fsti 2024-05-14 15:56:45.505355187 +0200 @@ -63,32 +63,27 @@ Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE +! v_CPA_PKE_CIPHERTEXT_SIZE_512_ @@ -2856,8 +3263,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber512.fsti extraction-secret-in Prims.l_True (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst extraction-secret-independent/Libcrux.Kem.Kyber.Kyber768.fst ---- extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-14 15:56:45.424356515 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber768.fst 2024-05-14 15:56:45.482355564 +0200 @@ -3,37 +3,22 @@ open Core open FStar.Mul @@ -2906,8 +3313,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber768.fst extraction-secret-ind (sz 2400) (sz 1184) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Kyber768.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-14 15:56:45.451356072 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Kyber768.fsti 2024-05-14 15:56:45.494355367 +0200 @@ -63,33 +63,27 @@ Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE +! v_CPA_PKE_CIPHERTEXT_SIZE_768_ @@ -2939,13 +3346,13 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti extraction-secret-in + (public_key: Libcrux.Kem.Kyber.Types.t_KyberPublicKey (sz 1184)) (randomness: t_Array u8 (sz 32)) - : Prims.Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext (sz 1088) & t_Array u8 (sz 32)) -+ : Prims.Pure (Libcrux.Kem.Kyber.Types.t_KyberCiphertext (sz 1088) & t_Array u8 (sz 32)) - Prims.l_True +- Prims.l_True - (ensures (fun (ct,ss)-> (ct.f_value,ss) == Spec.Kyber.kyber768_encapsulate public_key.f_value randomness)) - -val validate_public_key (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184)) - : Prims.Pure (Core.Option.t_Option (Libcrux.Kem.Kyber.Types.t_MlKemPublicKey (sz 1184))) -- Prims.l_True ++ : Prims.Pure (Libcrux.Kem.Kyber.Types.t_KyberCiphertext (sz 1088) & t_Array u8 (sz 32)) + Prims.l_True (fun _ -> Prims.l_True) -val generate_key_pair (randomness: t_Array u8 (sz 64)) @@ -2956,8 +3363,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Kyber768.fsti extraction-secret-in - (ensures (fun kp -> (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.kyber768_generate_keypair randomness)) + (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-independent/Libcrux.Kem.Kyber.Matrix.fst ---- extraction-edited/Libcrux.Kem.Kyber.Matrix.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Matrix.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Matrix.fst 2024-05-14 15:56:45.428356450 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Matrix.fst 2024-05-14 15:56:45.508355137 +0200 @@ -3,418 +3,432 @@ open Core open FStar.Mul @@ -2973,14 +3380,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in - let result:t_Array wfPolynomialRingElement v_K = - Rust_primitives.Hax.repeat wfZero v_K -+let compute_As_plus_e -+ (v_K: usize) -+ (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -+ (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ = -+ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K - in +- in - [@ inline_let] - let inv0 = fun (acc:t_Array wfPolynomialRingElement v_K) (i:usize) -> - (v i <= v v_K) /\ @@ -2990,6 +3390,14 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - let result:t_Array wfPolynomialRingElement v_K = - Rust_primitives.Iterators.foldi_slice #(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) #(t_Array wfPolynomialRingElement v_K) #inv0 - matrix_A ++let compute_As_plus_e ++ (v_K: usize) ++ (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) ++ (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ = ++ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in + let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate + (Core.Slice.impl__iter (Rust_primitives.unsize matrix_A @@ -3175,17 +3583,24 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - assert (forall (j:usize). (v j >= v i + 1 /\ v j < v v_K) ==> derefine_poly_b result.[j] == derefine_poly_b orig_result.[j]); - assume (inv0 result (i +! sz 1)); - result) -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement))) - in +- in - admit(); //P-F - result -#pop-options ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement))) ++ in + result -#push-options "--ifuel 0 --z3rlimit 100" -let compute_message #p v_K m_v secret_as_ntt u_as_ntt = - let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = - Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO +- in +- let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) in +- [@ inline_let] +- let inv = fun (acc:acc_t) (i:usize) -> +- (v i <= v v_K) /\ +- (poly_range #(v v_K * 3328) acc (v i * 3328)) +let compute_message + (v_K: usize) + (v: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) @@ -3194,12 +3609,6 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep + let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = + Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO in -- let acc_t = Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) in -- [@ inline_let] -- let inv = fun (acc:acc_t) (i:usize) -> -- (v i <= v v_K) /\ -- (poly_range #(v v_K * 3328) acc (v i * 3328)) -- in - let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = - Rust_primitives.Iterators.foldi_range #_ #acc_t #inv { + let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = @@ -3317,6 +3726,13 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep -let compute_ring_element_v v_K tt_as_ntt r_as_ntt error_2_ message = - let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = - Libcrux.Kem.Kyber.Arithmetic.cast_poly_b Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO +- in +- [@ inline_let] +- let inv = fun (acc:t_PolynomialRingElement_b (v v_K * 3328)) (i:usize) -> +- (v i <= 256) /\ +- (poly_range acc (v i * 3328)) in +- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = +- Rust_primitives.Iterators.foldi_range #_ #_ #inv ({ +let compute_ring_element_v + (v_K: usize) + (tt_as_ntt r_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) @@ -3324,13 +3740,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep + = + let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = + Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO - in -- [@ inline_let] -- let inv = fun (acc:t_PolynomialRingElement_b (v v_K * 3328)) (i:usize) -> -- (v i <= 256) /\ -- (poly_range acc (v i * 3328)) in -- let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328) = -- Rust_primitives.Iterators.foldi_range #_ #_ #inv ({ ++ in + let result:Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ Core.Ops.Range.f_start = sz 0; @@ -3447,12 +3857,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - let wfZero: wfPolynomialRingElement = (Libcrux.Kem.Kyber.Arithmetic.cast_poly_b #1 #3328 Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO) in - let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Hax.repeat wfZero v_K -+ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -+ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ = -+ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = -+ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K - in +- in - let acc_t = t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K in - [@ inline_let] - let inv0 = fun (acc:t_Array wfPolynomialRingElement v_K) (i:usize) -> @@ -3462,6 +3867,12 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - let result:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = - Rust_primitives.Iterators.foldi_slice #(t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K) #acc_t #inv0 - a_as_ntt ++ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) ++ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ = ++ let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = ++ Rust_primitives.Hax.repeat Libcrux.Kem.Kyber.Arithmetic.impl__PolynomialRingElement__ZERO v_K ++ in + let result:t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K = + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter (Core.Iter.Traits.Iterator.f_enumerate + (Core.Slice.impl__iter (Rust_primitives.unsize a_as_ntt @@ -3563,11 +3974,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - (forall (j:usize). (v j > v i /\ v j < v v_K) ==> acc.[j] == orig_result_cast.[j]) /\ - (forall (j:usize). (v j < v inner) ==> (i32_range (acc.[i] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64*v v_K * 3328)).f_coefficients.[j] 3328)) - // And all indexes above v inner are unchanged from result1 -+ (Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K -+ (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ <: -+ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) - in +- in - assert (forall (j:usize). (v j < v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); - assert (forall (j:usize). (v j > v i /\ v j < v v_K) ==> result.[j] == orig_result_cast.[j]); - assert (inv2 result (sz 0)); @@ -3576,6 +3983,11 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - Core.Ops.Range.f_start = sz 0; - Core.Ops.Range.f_end = Libcrux.Kem.Kyber.Constants.v_COEFFICIENTS_IN_RING_ELEMENT - } ++ (Libcrux.Kem.Kyber.Ntt.invert_ntt_montgomery v_K ++ (result.[ i ] <: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ <: ++ Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ in + Core.Iter.Traits.Iterator.f_fold (Core.Iter.Traits.Collect.f_into_iter ({ + Core.Ops.Range.f_start = sz 0; + Core.Ops.Range.f_end @@ -3761,8 +4173,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fst extraction-secret-indep - admit(); //P-F v_A_transpose diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Matrix.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-14 15:56:45.462355892 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Matrix.fsti 2024-05-14 15:56:45.478355629 +0200 @@ -3,71 +3,39 @@ open Core open FStar.Mul @@ -3783,13 +4195,13 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti extraction-secret-inde - (to_spec_matrix_b #p matrix_A) - (to_spec_vector_b #p s_as_ntt) - (to_spec_vector_b #p error_as_ntt)) +- + (matrix_A: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) + (s_as_ntt error_as_ntt: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) + Prims.l_True + (fun _ -> Prims.l_True) -- -val compute_message (#p:Spec.Kyber.params) +val compute_message (v_K: usize) @@ -3844,12 +4256,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti extraction-secret-inde - let e_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p error_1_ in - let res_spec = Libcrux.Kem.Kyber.Arithmetic.to_spec_vector_b #p res in - res_spec == Spec.Kyber.(vector_add (vector_inv_ntt (matrix_vector_mul a_spec r_spec)) e_spec)) -+ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) -+ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) -+ Prims.l_True -+ (fun _ -> Prims.l_True) - +- - - -val sample_matrix_A (#p:Spec.Kyber.params) (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) @@ -3859,13 +4266,19 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Matrix.fsti extraction-secret-inde - let matrix_A = Spec.Kyber.sample_matrix_A #p (Seq.slice seed 0 32) in - if transpose then Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p res == matrix_A - else Libcrux.Kem.Kyber.Arithmetic.to_spec_matrix_b #p res == Spec.Kyber.matrix_transpose matrix_A) ++ (a_as_ntt: t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) ++ (r_as_ntt error_1_: t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ : Prims.Pure (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ +val sample_matrix_A (v_K: usize) (seed: t_Array u8 (sz 34)) (transpose: bool) + : Prims.Pure (t_Array (t_Array Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement v_K) v_K) + Prims.l_True + (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fst extraction-secret-independent/Libcrux.Kem.Kyber.Ntt.fst ---- extraction-edited/Libcrux.Kem.Kyber.Ntt.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Ntt.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Ntt.fst 2024-05-14 15:56:45.431356400 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Ntt.fst 2024-05-14 15:56:45.483355547 +0200 @@ -1,130 +1,56 @@ module Libcrux.Kem.Kyber.Ntt -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" @@ -3873,15 +4286,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fst extraction-secret-independ open Core open FStar.Mul -+let ntt_multiply_binomials (a0, a1: (i32 & i32)) (b0, b1: (i32 & i32)) (zeta: i32) = -+ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b0 <: i32) +! -+ ((Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (a1 *! b1 <: i32) <: i32) *! zeta <: i32) -+ <: -+ i32), -+ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b1 <: i32) +! (a1 *! b0 <: i32) <: i32) -+ <: -+ (i32 & i32) - +- -let v_ZETAS_TIMES_MONTGOMERY_R = - let list : list (i32_b 1664) = - [ @@ -3951,6 +4356,15 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fst extraction-secret-independ - -#push-options "--ifuel 0 --z3rlimit 1200" -let invert_ntt_at_layer #v_K #b zeta_i re layer = ++let ntt_multiply_binomials (a0, a1: (i32 & i32)) (b0, b1: (i32 & i32)) (zeta: i32) = ++ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b0 <: i32) +! ++ ((Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce (a1 *! b1 <: i32) <: i32) *! zeta <: i32) ++ <: ++ i32), ++ Libcrux.Kem.Kyber.Arithmetic.montgomery_reduce ((a0 *! b1 <: i32) +! (a1 *! b0 <: i32) <: i32) ++ <: ++ (i32 & i32) ++ +let invert_ntt_at_layer + (zeta_i: usize) + (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) @@ -4185,8 +4599,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fst extraction-secret-independ in - re -#pop-options -+ re - +- -#push-options "--z3rlimit 500" -val mul_zeta_red2 (#b:nat{b <= 31175}) - (zeta_i:usize{v zeta_i >= 0 /\ v zeta_i <= 63} ) @@ -4204,7 +4617,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fst extraction-secret-independ - (v_ZETAS_TIMES_MONTGOMERY_R.[ zeta_i ] <: i32) in - red -#pop-options -- ++ re + -#push-options "--ifuel 0 --z3rlimit 5000" -let ntt_at_layer #b zeta_i re layer initial_coefficient_bound = - let step = sz 1 < (i32 & i32) -> zeta: i32 ++ -> Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) ++ ++val invert_ntt_at_layer ++ (zeta_i: usize) ++ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ (layer: usize) ++ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ ++val invert_ntt_montgomery (v_K: usize) (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Prims.l_True ++ (fun _ -> Prims.l_True) -val ntt_multiply_binomials (a:wfFieldElement&wfFieldElement) (b: wfFieldElement&wfFieldElement) (zeta: i32_b 1664) : - Pure (wfFieldElement & wfFieldElement) - (requires True) - (ensures (fun _ -> True)) -+val ntt_multiply_binomials: (i32 & i32) -> (i32 & i32) -> zeta: i32 -+ -> Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) - +- -val invert_ntt_at_layer (#v_K:usize{v v_K >= 1 /\ v v_K <= 4}) - (#b:nat{b <= v v_K * 3328 * 64}) - (zeta_i: usize{v zeta_i >= 1 /\ v zeta_i <= 128}) @@ -4839,10 +5267,10 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen - v zeta_i == pow2 (8 - v layer) /\ - b == v v_K * 3328 * pow2(v layer - 1)}) - : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (2*b)) -+val invert_ntt_at_layer ++val ntt_at_layer + (zeta_i: usize) + (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (layer: usize) ++ (layer initial_coefficient_bound: usize) + : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) Prims.l_True - (fun x -> let (zeta_fin,re) = x in v zeta_fin == pow2 (7 - v layer)) @@ -4851,11 +5279,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen -val invert_ntt_montgomery (v_K: usize{v v_K >= 1 /\ v v_K <= 4}) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (v v_K * 3328)) - : Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (64 * v v_K * 3328) -+val invert_ntt_montgomery (v_K: usize) (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Prims.l_True -+ (fun _ -> Prims.l_True) - +- -val ntt_at_layer - (#b:nat{b <= 31175}) - (zeta_i: usize{v zeta_i < 128}) @@ -4867,14 +5291,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen - : Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b (3328+b)) - (requires True) - (ensures fun (zeta_i, result) -> v zeta_i == pow2 (8 - v layer) - 1) -+val ntt_at_layer -+ (zeta_i: usize) -+ (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ (layer initial_coefficient_bound: usize) -+ : Prims.Pure (usize & Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ Prims.l_True -+ (fun _ -> Prims.l_True) - +- -val ntt_at_layer_3_ (#b:nat) - (zeta_i: usize{v zeta_i < 128}) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b b) @@ -4908,11 +5325,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen Prims.l_True - (ensures fun (zeta_i,result) -> v zeta_i == pow2 (8 - v layer) - 1) + (fun _ -> Prims.l_True) - --val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7) -- : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) -- (requires True) -- (ensures (fun _ -> True)) ++ +val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) + : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement + (requires @@ -4966,13 +5379,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen + bool) + <: + bool)) - --val ntt_multiply (lhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -- (rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -- : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) -- (requires True) -- (ensures (fun _ -> True)) -- ++ +val ntt_multiply (lhs rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) + : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement + (requires @@ -5024,7 +5431,18 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen + bool) + <: + bool)) -+ + +-val ntt_binomially_sampled_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 7) +- : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) +- (requires True) +- (ensures (fun _ -> True)) +- +-val ntt_multiply (lhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) +- (rhs: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) +- : Prims.Pure (Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) +- (requires True) +- (ensures (fun _ -> True)) +- val ntt_vector_u (v_VECTOR_U_COMPRESSION_FACTOR: usize) - (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement_b 3328) @@ -5086,8 +5504,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Ntt.fsti extraction-secret-indepen + <: + bool)) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Sampling.fst extraction-secret-independent/Libcrux.Kem.Kyber.Sampling.fst ---- extraction-edited/Libcrux.Kem.Kyber.Sampling.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Sampling.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Sampling.fst 2024-05-14 15:56:45.466355826 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Sampling.fst 2024-05-14 15:56:45.515355022 +0200 @@ -3,34 +3,27 @@ open Core open FStar.Mul @@ -5524,8 +5942,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Sampling.fst extraction-secret-ind -#pop-options + out diff -ruN extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Sampling.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-14 15:56:45.436356318 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Sampling.fsti 2024-05-14 15:56:45.490355433 +0200 @@ -3,37 +3,77 @@ open Core open FStar.Mul @@ -5626,8 +6044,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Sampling.fsti extraction-secret-in + Prims.l_True + (fun _ -> Prims.l_True) diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fst extraction-secret-independent/Libcrux.Kem.Kyber.Serialize.fst ---- extraction-edited/Libcrux.Kem.Kyber.Serialize.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Serialize.fst 2024-05-07 18:38:45 +--- extraction-edited/Libcrux.Kem.Kyber.Serialize.fst 2024-05-14 15:56:45.454356023 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Serialize.fst 2024-05-14 15:56:45.498355301 +0200 @@ -1,15 +1,8 @@ module Libcrux.Kem.Kyber.Serialize -#set-options "--fuel 0 --ifuel 0 --z3rlimit 50 --retry 3" @@ -5770,11 +6188,12 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fst extraction-secret-in - bit_vec_equal_intro_principle (); - coefficient1, coefficient2 -#pop-options -+ coefficient1, coefficient2 <: (i32 & i32) - +- -#push-options "--z3rlimit 400" -[@@"opaque_to_smt"] -let decompress_coefficients_5_ byte1 byte2 byte3 byte4 byte5 = ++ coefficient1, coefficient2 <: (i32 & i32) ++ +let decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: i32) = let coefficient1:i32 = byte1 &. 31l in let coefficient2:i32 = ((byte2 &. 3l <: i32) <>! 5l <: i32) in @@ -5800,9 +6219,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fst extraction-secret-in coefficient7, coefficient8 -#pop-options -+ <: -+ (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) - +- -let cast_bound_lemma - #t #u - (n: int_t t) @@ -5829,7 +6246,9 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fst extraction-secret-in -#pop-options - -#restart-solver -- ++ <: ++ (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) + -#push-options "--fuel 0 --ifuel 1 --query_stats --z3rlimit 100" -[@@"opaque_to_smt"] let compress_then_serialize_10_ @@ -7110,8 +7529,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fst extraction-secret-in -#pop-options - diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-independent/Libcrux.Kem.Kyber.Serialize.fsti ---- extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-07 18:38:46 +--- extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-14 15:56:45.468355794 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Serialize.fsti 2024-05-14 15:56:45.476355662 +0200 @@ -2,188 +2,118 @@ #set-options "--fuel 0 --ifuel 1 --z3rlimit 15" open Core @@ -7140,9 +7559,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - (create8 (coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8)) 11 - (create11 tuple) 8 - ) -+ Prims.l_True -+ (fun _ -> Prims.l_True) - +- -val compress_coefficients_3_ (coefficient1 coefficient2: int_t_d u16_inttype 12) - : Prims.Pure (u8 & u8 & u8) - (requires True) @@ -7151,6 +7568,9 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - (create2 (coefficient1, coefficient2)) 12 - (create3 tuple) 8 - ) ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ +val compress_coefficients_3_ (coefficient1 coefficient2: u16) + : Prims.Pure (u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) @@ -7163,10 +7583,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - (create8 (coefficient1, coefficient2, coefficient3, coefficient4, coefficient5, coefficient6, coefficient7, coefficient8)) 5 - (create5 tuple) 8 - ) -+ (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: -+ u8) -+ : Prims.Pure (u8 & u8 & u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) - +- -private unfold type i32_d = int_t_d i32_inttype -val decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: int_t_d i32_inttype 8) - : Prims.Pure (i32_d 10 & i32_d 10 & i32_d 10 & i32_d 10) @@ -7176,6 +7593,10 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - (create5 (byte1, byte2, byte3, byte4, byte5)) 8 - (create4 #i32 (r1, r2, r3, r4)) 10 - ) ++ (coefficient2 coefficient1 coefficient4 coefficient3 coefficient5 coefficient7 coefficient6 coefficient8: ++ u8) ++ : Prims.Pure (u8 & u8 & u8 & u8 & u8) Prims.l_True (fun _ -> Prims.l_True) ++ +val decompress_coefficients_10_ (byte2 byte1 byte3 byte4 byte5: i32) + : Prims.Pure (i32 & i32 & i32 & i32) Prims.l_True (fun _ -> Prims.l_True) @@ -7201,8 +7622,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - (create1 byte) 8 - (create2 #i32 (r1, r2)) 4 - ) -+ : Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) - +- -val decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: int_t_d i32_inttype 8) - : Prims.Pure (i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5 & i32_d 5) - (requires True) @@ -7211,6 +7631,8 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - (create5 #i32 (byte1, byte2, byte3, byte4, byte5)) 8 - (create8 #i32 (r1, r2, r3, r4, r5, r6, r7, r8)) 5 - ) ++ : Prims.Pure (i32 & i32) Prims.l_True (fun _ -> Prims.l_True) ++ +val decompress_coefficients_5_ (byte1 byte2 byte3 byte4 byte5: i32) + : Prims.Pure (i32 & i32 & i32 & i32 & i32 & i32 & i32 & i32) + Prims.l_True @@ -7272,14 +7694,14 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i + (v_COMPRESSION_FACTOR v_OUT_LEN: usize) + (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) - --val deserialize_then_decompress_10_ (serialized: t_Slice u8 {Seq.length serialized == 320}) -- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement ++ +val compress_then_serialize_ring_element_v + (v_COMPRESSION_FACTOR v_OUT_LEN: usize) + (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) + : Prims.Pure (t_Array u8 v_OUT_LEN) Prims.l_True (fun _ -> Prims.l_True) -+ + +-val deserialize_then_decompress_10_ (serialized: t_Slice u8 {Seq.length serialized == 320}) +- : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement +val deserialize_then_decompress_10_ (serialized: t_Slice u8) + : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement Prims.l_True @@ -7351,10 +7773,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - : Pure (Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - (requires (length serialized == Spec.Kyber.v_BYTES_PER_RING_ELEMENT)) - (ensures fun _ -> True) -+ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement -+ Prims.l_True -+ (fun _ -> Prims.l_True) - +- -val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement) - : Pure (t_Array u8 (sz 384)) - (requires True) @@ -7362,256 +7781,68 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Serialize.fsti extraction-secret-i - let coefficients: t_Array _ (sz 256) = Spec.Kyber.map' Libcrux.Kem.Kyber.Arithmetic.to_unsigned_representative re.f_coefficients in - int_t_array_bitwise_eq res 8 coefficients 12 - )) -+val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) -+ : Prims.Pure (t_Array u8 (sz 384)) Prims.l_True (fun _ -> Prims.l_True) -diff -ruN extraction-edited/Libcrux.Kem.Kyber.Types.fst extraction-secret-independent/Libcrux.Kem.Kyber.Types.fst ---- extraction-edited/Libcrux.Kem.Kyber.Types.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.Types.fst 2024-05-07 18:38:45 -@@ -3,275 +3,193 @@ - open Core - open FStar.Mul - --type t_MlKemCiphertext (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } -+type t_KyberCiphertext (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_1 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemCiphertext v_SIZE) (t_Slice u8) = -- { -- f_as_ref_pre = (fun (self: t_MlKemCiphertext v_SIZE) -> true); -- f_as_ref_post = (fun (self: t_MlKemCiphertext v_SIZE) (out: t_Slice u8) -> true); -- f_as_ref = fun (self: t_MlKemCiphertext v_SIZE) -> Rust_primitives.unsize self.f_value -- } -+let impl_1 (v_SIZE: usize) : Core.Convert.t_AsRef (t_KyberCiphertext v_SIZE) (t_Slice u8) = -+ { f_as_ref = fun (self: t_KyberCiphertext v_SIZE) -> Rust_primitives.unsize self.f_value } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_2 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = -- { -- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); -- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemCiphertext v_SIZE) -> true); -- f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemCiphertext v_SIZE -- } -+let impl_2 (v_SIZE: usize) : Core.Convert.t_From (t_KyberCiphertext v_SIZE) (t_Array u8 v_SIZE) = -+ { f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_KyberCiphertext v_SIZE } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = -+let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_KyberCiphertext v_SIZE) (t_Array u8 v_SIZE) = - { -- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); -- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemCiphertext v_SIZE) -> true); - f_from - = - fun (value: t_Array u8 v_SIZE) -> -- { f_value = Core.Clone.f_clone value } <: t_MlKemCiphertext v_SIZE -+ { f_value = Core.Clone.f_clone value } <: t_KyberCiphertext v_SIZE - } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_4 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemCiphertext v_SIZE) = -- { -- f_from_pre = (fun (value: t_MlKemCiphertext v_SIZE) -> true); -- f_from_post = (fun (value: t_MlKemCiphertext v_SIZE) (out: t_Array u8 v_SIZE) -> true); -- f_from = fun (value: t_MlKemCiphertext v_SIZE) -> value.f_value -- } -+let impl_4 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_KyberCiphertext v_SIZE) = -+ { f_from = fun (value: t_KyberCiphertext v_SIZE) -> value.f_value } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = -+let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_KyberCiphertext v_SIZE) (t_Slice u8) = - { - f_Error = Core.Array.t_TryFromSliceError; -- f_try_from_pre = (fun (value: t_Slice u8) -> true); -- f_try_from_post -- = -- (fun -- (value: t_Slice u8) -- (out: Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError) -- -> -- true); - f_try_from - = - fun (value: t_Slice u8) -> - match Core.Convert.f_try_into value with - | Core.Result.Result_Ok value -> -- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) -+ Core.Result.Result_Ok ({ f_value = value } <: t_KyberCiphertext v_SIZE) - <: -- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError -+ Core.Result.t_Result (t_KyberCiphertext v_SIZE) Core.Array.t_TryFromSliceError - | Core.Result.Result_Err e -> - Core.Result.Result_Err e - <: -- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError -+ Core.Result.t_Result (t_KyberCiphertext v_SIZE) Core.Array.t_TryFromSliceError - } - --let impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : t_Array u8 v_SIZE = -+let impl_6__as_slice (v_SIZE: usize) (self: t_KyberCiphertext v_SIZE) : t_Array u8 v_SIZE = - self.f_value - --let impl_6__len (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : usize = v_SIZE -+let impl_6__len (v_SIZE: usize) (self: t_KyberCiphertext v_SIZE) : usize = v_SIZE - --let impl_6__split_at (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) (mid: usize) -- : Pure (t_Slice u8 & t_Slice u8) -- (requires (mid <=. v_SIZE)) -- (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = -+let impl_6__split_at (v_SIZE: usize) (self: t_KyberCiphertext v_SIZE) (mid: usize) -+ : (t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid - --type t_MlKemPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } -+type t_KyberPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_7 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = -- { -- f_as_ref_pre = (fun (self: t_MlKemPrivateKey v_SIZE) -> true); -- f_as_ref_post = (fun (self: t_MlKemPrivateKey v_SIZE) (out: t_Slice u8) -> true); -- f_as_ref = fun (self: t_MlKemPrivateKey v_SIZE) -> Rust_primitives.unsize self.f_value -- } -+let impl_7 (v_SIZE: usize) : Core.Convert.t_AsRef (t_KyberPrivateKey v_SIZE) (t_Slice u8) = -+ { f_as_ref = fun (self: t_KyberPrivateKey v_SIZE) -> Rust_primitives.unsize self.f_value } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_8 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = -- { -- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); -- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPrivateKey v_SIZE) -> true); -- f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPrivateKey v_SIZE -- } -+let impl_8 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPrivateKey v_SIZE) (t_Array u8 v_SIZE) = -+ { f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_KyberPrivateKey v_SIZE } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = -+let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPrivateKey v_SIZE) (t_Array u8 v_SIZE) = - { -- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); -- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPrivateKey v_SIZE) -> true); - f_from - = - fun (value: t_Array u8 v_SIZE) -> -- { f_value = Core.Clone.f_clone value } <: t_MlKemPrivateKey v_SIZE -+ { f_value = Core.Clone.f_clone value } <: t_KyberPrivateKey v_SIZE - } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPrivateKey v_SIZE) = -- { -- f_from_pre = (fun (value: t_MlKemPrivateKey v_SIZE) -> true); -- f_from_post = (fun (value: t_MlKemPrivateKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); -- f_from = fun (value: t_MlKemPrivateKey v_SIZE) -> value.f_value -- } -+let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_KyberPrivateKey v_SIZE) = -+ { f_from = fun (value: t_KyberPrivateKey v_SIZE) -> value.f_value } - - [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = -+let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_KyberPrivateKey v_SIZE) (t_Slice u8) = - { - f_Error = Core.Array.t_TryFromSliceError; -- f_try_from_pre = (fun (value: t_Slice u8) -> true); -- f_try_from_post -- = -- (fun -- (value: t_Slice u8) -- (out: Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError) -- -> -- true); - f_try_from - = - fun (value: t_Slice u8) -> - match Core.Convert.f_try_into value with - | Core.Result.Result_Ok value -> -- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) -+ Core.Result.Result_Ok ({ f_value = value } <: t_KyberPrivateKey v_SIZE) - <: -- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError -+ Core.Result.t_Result (t_KyberPrivateKey v_SIZE) Core.Array.t_TryFromSliceError - | Core.Result.Result_Err e -> - Core.Result.Result_Err e - <: -- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError -+ Core.Result.t_Result (t_KyberPrivateKey v_SIZE) Core.Array.t_TryFromSliceError - } - --let impl_12__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : t_Array u8 v_SIZE = -+let impl_12__as_slice (v_SIZE: usize) (self: t_KyberPrivateKey v_SIZE) : t_Array u8 v_SIZE = - self.f_value - --let impl_12__len (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : usize = v_SIZE -+let impl_12__len (v_SIZE: usize) (self: t_KyberPrivateKey v_SIZE) : usize = v_SIZE - --let impl_12__split_at (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) (mid: usize) -- : Pure (t_Slice u8 & t_Slice u8) -- (requires (mid <=. v_SIZE)) -- (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = -+let impl_12__split_at (v_SIZE: usize) (self: t_KyberPrivateKey v_SIZE) (mid: usize) -+ : (t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid ++ : Prims.Pure Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement ++ Prims.l_True ++ (fun _ -> Prims.l_True) ++ ++val serialize_uncompressed_ring_element (re: Libcrux.Kem.Kyber.Arithmetic.t_PolynomialRingElement) ++ : Prims.Pure (t_Array u8 (sz 384)) Prims.l_True (fun _ -> Prims.l_True) +diff -ruN extraction-edited/Libcrux.Kem.Kyber.Types.fst extraction-secret-independent/Libcrux.Kem.Kyber.Types.fst +--- extraction-edited/Libcrux.Kem.Kyber.Types.fst 2024-05-14 15:56:45.464355859 +0200 ++++ extraction-secret-independent/Libcrux.Kem.Kyber.Types.fst 2024-05-14 15:56:45.493355383 +0200 +@@ -3,275 +3,193 @@ + open Core + open FStar.Mul -+type t_KyberPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } +-type t_MlKemCiphertext (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } ++type t_KyberCiphertext (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } -- -- -- -- -- -- -- -- -- --type t_MlKemPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } -- [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_13 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPublicKey v_SIZE) (t_Slice u8) = +-let impl_1 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemCiphertext v_SIZE) (t_Slice u8) = - { -- f_as_ref_pre = (fun (self: t_MlKemPublicKey v_SIZE) -> true); -- f_as_ref_post = (fun (self: t_MlKemPublicKey v_SIZE) (out: t_Slice u8) -> true); -- f_as_ref = fun (self: t_MlKemPublicKey v_SIZE) -> Rust_primitives.unsize self.f_value +- f_as_ref_pre = (fun (self: t_MlKemCiphertext v_SIZE) -> true); +- f_as_ref_post = (fun (self: t_MlKemCiphertext v_SIZE) (out: t_Slice u8) -> true); +- f_as_ref = fun (self: t_MlKemCiphertext v_SIZE) -> Rust_primitives.unsize self.f_value - } -+let impl_13 (v_SIZE: usize) : Core.Convert.t_AsRef (t_KyberPublicKey v_SIZE) (t_Slice u8) = -+ { f_as_ref = fun (self: t_KyberPublicKey v_SIZE) -> Rust_primitives.unsize self.f_value } ++let impl_1 (v_SIZE: usize) : Core.Convert.t_AsRef (t_KyberCiphertext v_SIZE) (t_Slice u8) = ++ { f_as_ref = fun (self: t_KyberCiphertext v_SIZE) -> Rust_primitives.unsize self.f_value } [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_14 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = +-let impl_2 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = - { - f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); -- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPublicKey v_SIZE) -> true); -- f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPublicKey v_SIZE +- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemCiphertext v_SIZE) -> true); +- f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemCiphertext v_SIZE - } -+let impl_14 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPublicKey v_SIZE) (t_Array u8 v_SIZE) = -+ { f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_KyberPublicKey v_SIZE } ++let impl_2 (v_SIZE: usize) : Core.Convert.t_From (t_KyberCiphertext v_SIZE) (t_Array u8 v_SIZE) = ++ { f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_KyberCiphertext v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_15 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = -+let impl_15 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPublicKey v_SIZE) (t_Array u8 v_SIZE) = +-let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemCiphertext v_SIZE) (t_Array u8 v_SIZE) = ++let impl_3 (v_SIZE: usize) : Core.Convert.t_From (t_KyberCiphertext v_SIZE) (t_Array u8 v_SIZE) = { - f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); -- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPublicKey v_SIZE) -> true); +- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemCiphertext v_SIZE) -> true); f_from = fun (value: t_Array u8 v_SIZE) -> -- { f_value = Core.Clone.f_clone value } <: t_MlKemPublicKey v_SIZE -+ { f_value = Core.Clone.f_clone value } <: t_KyberPublicKey v_SIZE +- { f_value = Core.Clone.f_clone value } <: t_MlKemCiphertext v_SIZE ++ { f_value = Core.Clone.f_clone value } <: t_KyberCiphertext v_SIZE } [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPublicKey v_SIZE) = +-let impl_4 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemCiphertext v_SIZE) = - { -- f_from_pre = (fun (value: t_MlKemPublicKey v_SIZE) -> true); -- f_from_post = (fun (value: t_MlKemPublicKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); -- f_from = fun (value: t_MlKemPublicKey v_SIZE) -> value.f_value +- f_from_pre = (fun (value: t_MlKemCiphertext v_SIZE) -> true); +- f_from_post = (fun (value: t_MlKemCiphertext v_SIZE) (out: t_Array u8 v_SIZE) -> true); +- f_from = fun (value: t_MlKemCiphertext v_SIZE) -> value.f_value - } -+let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_KyberPublicKey v_SIZE) = -+ { f_from = fun (value: t_KyberPublicKey v_SIZE) -> value.f_value } ++let impl_4 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_KyberCiphertext v_SIZE) = ++ { f_from = fun (value: t_KyberCiphertext v_SIZE) -> value.f_value } [@@ FStar.Tactics.Typeclasses.tcinstance] --let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) (t_Slice u8) = -+let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_KyberPublicKey v_SIZE) (t_Slice u8) = +-let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemCiphertext v_SIZE) (t_Slice u8) = ++let impl_5 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_KyberCiphertext v_SIZE) (t_Slice u8) = { f_Error = Core.Array.t_TryFromSliceError; - f_try_from_pre = (fun (value: t_Slice u8) -> true); @@ -7619,7 +7850,7 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Types.fst extraction-secret-indepe - = - (fun - (value: t_Slice u8) -- (out: Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError) +- (out: Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError) - -> - true); f_try_from @@ -7627,481 +7858,291 @@ diff -ruN extraction-edited/Libcrux.Kem.Kyber.Types.fst extraction-secret-indepe fun (value: t_Slice u8) -> match Core.Convert.f_try_into value with | Core.Result.Result_Ok value -> -- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPublicKey v_SIZE) -+ Core.Result.Result_Ok ({ f_value = value } <: t_KyberPublicKey v_SIZE) +- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemCiphertext v_SIZE) ++ Core.Result.Result_Ok ({ f_value = value } <: t_KyberCiphertext v_SIZE) <: -- Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError -+ Core.Result.t_Result (t_KyberPublicKey v_SIZE) Core.Array.t_TryFromSliceError +- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError ++ Core.Result.t_Result (t_KyberCiphertext v_SIZE) Core.Array.t_TryFromSliceError | Core.Result.Result_Err e -> Core.Result.Result_Err e <: -- Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError -+ Core.Result.t_Result (t_KyberPublicKey v_SIZE) Core.Array.t_TryFromSliceError +- Core.Result.t_Result (t_MlKemCiphertext v_SIZE) Core.Array.t_TryFromSliceError ++ Core.Result.t_Result (t_KyberCiphertext v_SIZE) Core.Array.t_TryFromSliceError } --let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : t_Array u8 v_SIZE = -+let impl_18__as_slice (v_SIZE: usize) (self: t_KyberPublicKey v_SIZE) : t_Array u8 v_SIZE = +-let impl_6__as_slice (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : t_Array u8 v_SIZE = ++let impl_6__as_slice (v_SIZE: usize) (self: t_KyberCiphertext v_SIZE) : t_Array u8 v_SIZE = self.f_value --let impl_18__len (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : usize = v_SIZE -+let impl_18__len (v_SIZE: usize) (self: t_KyberPublicKey v_SIZE) : usize = v_SIZE +-let impl_6__len (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) : usize = v_SIZE ++let impl_6__len (v_SIZE: usize) (self: t_KyberCiphertext v_SIZE) : usize = v_SIZE --let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) +-let impl_6__split_at (v_SIZE: usize) (self: t_MlKemCiphertext v_SIZE) (mid: usize) - : Pure (t_Slice u8 & t_Slice u8) - (requires (mid <=. v_SIZE)) - (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = -+let impl_18__split_at (v_SIZE: usize) (self: t_KyberPublicKey v_SIZE) (mid: usize) ++let impl_6__split_at (v_SIZE: usize) (self: t_KyberCiphertext v_SIZE) (mid: usize) + : (t_Slice u8 & t_Slice u8) = Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid --type t_MlKemKeyPair (v_PRIVATE_KEY_SIZE: usize) (v_PUBLIC_KEY_SIZE: usize) = { -- f_sk:t_MlKemPrivateKey v_PRIVATE_KEY_SIZE; -- f_pk:t_MlKemPublicKey v_PUBLIC_KEY_SIZE -+type t_KyberKeyPair (v_PRIVATE_KEY_SIZE: usize) (v_PUBLIC_KEY_SIZE: usize) = { -+ f_sk:t_KyberPrivateKey v_PRIVATE_KEY_SIZE; -+ f_pk:t_KyberPublicKey v_PUBLIC_KEY_SIZE - } - - let impl__from - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) -- (sk: t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) -- (pk: t_MlKemPublicKey v_PUBLIC_KEY_SIZE) -- : t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = -- { f_sk = sk; f_pk = pk } <: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE -+ (sk: t_KyberPrivateKey v_PRIVATE_KEY_SIZE) -+ (pk: t_KyberPublicKey v_PUBLIC_KEY_SIZE) -+ : t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = -+ { f_sk = sk; f_pk = pk } <: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE - - let impl__new - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) - (sk: t_Array u8 v_PRIVATE_KEY_SIZE) - (pk: t_Array u8 v_PUBLIC_KEY_SIZE) -- : t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = -+ : t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = - { f_sk = Core.Convert.f_into sk; f_pk = Core.Convert.f_into pk } - <: -- t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE -+ t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE - - let impl__pk - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) -- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -+ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - : t_Array u8 v_PUBLIC_KEY_SIZE = impl_18__as_slice v_PUBLIC_KEY_SIZE self.f_pk - - let impl__private_key - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) -- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -- : t_MlKemPrivateKey v_PRIVATE_KEY_SIZE = self.f_sk -+ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -+ : t_KyberPrivateKey v_PRIVATE_KEY_SIZE = self.f_sk - - let impl__public_key - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) -- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -- : t_MlKemPublicKey v_PUBLIC_KEY_SIZE = self.f_pk -+ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -+ : t_KyberPublicKey v_PUBLIC_KEY_SIZE = self.f_pk +-type t_MlKemPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } ++type t_KyberPrivateKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } - let impl__sk - (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) -- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -+ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) - : t_Array u8 v_PRIVATE_KEY_SIZE = impl_12__as_slice v_PRIVATE_KEY_SIZE self.f_sk -diff -ruN extraction-edited/Libcrux.Kem.Kyber.fst extraction-secret-independent/Libcrux.Kem.Kyber.fst ---- extraction-edited/Libcrux.Kem.Kyber.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.fst 2024-05-07 18:38:45 -@@ -1,29 +1,12 @@ - module Libcrux.Kem.Kyber --#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" - open Core - open FStar.Mul + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_7 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = +- { +- f_as_ref_pre = (fun (self: t_MlKemPrivateKey v_SIZE) -> true); +- f_as_ref_post = (fun (self: t_MlKemPrivateKey v_SIZE) (out: t_Slice u8) -> true); +- f_as_ref = fun (self: t_MlKemPrivateKey v_SIZE) -> Rust_primitives.unsize self.f_value +- } ++let impl_7 (v_SIZE: usize) : Core.Convert.t_AsRef (t_KyberPrivateKey v_SIZE) (t_Slice u8) = ++ { f_as_ref = fun (self: t_KyberPrivateKey v_SIZE) -> Rust_primitives.unsize self.f_value } --let update_at_range_lemma #n -- (s: t_Slice 't) -- (i: Core.Ops.Range.t_Range (int_t n) {(Core.Ops.Range.impl_index_range_slice 't n).f_index_pre s i}) -- (x: t_Slice 't) -- : Lemma -- (requires (Seq.length x == v i.f_end - v i.f_start)) -- (ensures ( -- let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in -- let len = v i.f_start in -- forall (i: nat). i < len ==> Seq.index s i == Seq.index s' i -- )) -- [SMTPat (Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x)] -- = let s' = Rust_primitives.Hax.Monomorphized_update_at.update_at_range s i x in -- let len = v i.f_start in -- introduce forall (i:nat {i < len}). Seq.index s i == Seq.index s' i -- with (assert ( Seq.index (Seq.slice s 0 len) i == Seq.index s i -- /\ Seq.index (Seq.slice s' 0 len) i == Seq.index s' i )) -- --let serialize_kem_secret_key #p -+let serialize_kem_secret_key - (v_SERIALIZED_KEY_LEN: usize) -- (private_key public_key implicit_rejection_value: t_Slice u8) = -+ (private_key public_key implicit_rejection_value: t_Slice u8) -+ = - let out:t_Array u8 v_SERIALIZED_KEY_LEN = Rust_primitives.Hax.repeat 0uy v_SERIALIZED_KEY_LEN in - let pointer:usize = sz 0 in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = -@@ -72,8 +55,6 @@ - t_Slice u8) - in - let pointer:usize = pointer +! (Core.Slice.impl__len public_key <: usize) in -- let h_public_key = (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) -- <: t_Slice u8) in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = - Rust_primitives.Hax.Monomorphized_update_at.update_at_range out - ({ -@@ -89,7 +70,16 @@ - pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE <: usize - } - <: -- Core.Ops.Range.t_Range usize ]) h_public_key) -+ Core.Ops.Range.t_Range usize ] -+ <: -+ t_Slice u8) -+ (Rust_primitives.unsize (Libcrux.Kem.Kyber.Hash_functions.v_H public_key -+ <: -+ t_Array u8 (sz 32)) -+ <: -+ t_Slice u8) -+ <: -+ t_Slice u8) - in - let pointer:usize = pointer +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE in - let out:t_Array u8 v_SERIALIZED_KEY_LEN = -@@ -116,32 +106,14 @@ - <: - t_Slice u8) - in -- assert (Seq.slice out 0 (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) `Seq.equal` private_key); -- assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p)) -- (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) `Seq.equal` public_key); -- assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p)) -- (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! -- Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) -- `Seq.equal` Libcrux.Kem.Kyber.Hash_functions.v_H public_key); -- assert (Seq.slice out (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! -- Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)) -- (v #usize_inttype (Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p +! -- Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p +! -- Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE +! -- Spec.Kyber.v_SHARED_SECRET_SIZE)) -- == implicit_rejection_value); -- lemma_slice_append_4 out private_key public_key (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value; - out + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_8 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = +- { +- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); +- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPrivateKey v_SIZE) -> true); +- f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPrivateKey v_SIZE +- } ++let impl_8 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPrivateKey v_SIZE) (t_Array u8 v_SIZE) = ++ { f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_KyberPrivateKey v_SIZE } --let decapsulate #p -+let decapsulate - (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: - usize) -- (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) = -- let orig_secret_key = secret_key.f_value in -+ (secret_key: Libcrux.Kem.Kyber.Types.t_KyberPrivateKey v_SECRET_KEY_SIZE) -+ (ciphertext: Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE) -+ = - let ind_cpa_secret_key, secret_key:(t_Slice u8 & t_Slice u8) = - Libcrux.Kem.Kyber.Types.impl_12__split_at v_SECRET_KEY_SIZE secret_key v_CPA_SECRET_KEY_SIZE - in -@@ -151,12 +123,8 @@ - let ind_cpa_public_key_hash, implicit_rejection_value:(t_Slice u8 & t_Slice u8) = - Core.Slice.impl__split_at secret_key Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE - in -- assert (ind_cpa_secret_key == slice orig_secret_key (sz 0) v_CPA_SECRET_KEY_SIZE); -- assert (ind_cpa_public_key == slice orig_secret_key v_CPA_SECRET_KEY_SIZE (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE)); -- assert (ind_cpa_public_key_hash == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE) (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE)); -- assert (implicit_rejection_value == slice orig_secret_key (v_CPA_SECRET_KEY_SIZE +! v_PUBLIC_KEY_SIZE +! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) (length orig_secret_key)); - let decrypted:t_Array u8 (sz 32) = -- Libcrux.Kem.Kyber.Ind_cpa.decrypt #p v_K -+ Libcrux.Kem.Kyber.Ind_cpa.decrypt v_K - v_CIPHERTEXT_SIZE - v_C1_SIZE - v_VECTOR_U_COMPRESSION_FACTOR -@@ -184,9 +152,6 @@ + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPrivateKey v_SIZE) (t_Array u8 v_SIZE) = ++let impl_9 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPrivateKey v_SIZE) (t_Array u8 v_SIZE) = + { +- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); +- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPrivateKey v_SIZE) -> true); + f_from + = + fun (value: t_Array u8 v_SIZE) -> +- { f_value = Core.Clone.f_clone value } <: t_MlKemPrivateKey v_SIZE ++ { f_value = Core.Clone.f_clone value } <: t_KyberPrivateKey v_SIZE + } + + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPrivateKey v_SIZE) = +- { +- f_from_pre = (fun (value: t_MlKemPrivateKey v_SIZE) -> true); +- f_from_post = (fun (value: t_MlKemPrivateKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); +- f_from = fun (value: t_MlKemPrivateKey v_SIZE) -> value.f_value +- } ++let impl_10 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_KyberPrivateKey v_SIZE) = ++ { f_from = fun (value: t_KyberPrivateKey v_SIZE) -> value.f_value } + + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPrivateKey v_SIZE) (t_Slice u8) = ++let impl_11 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_KyberPrivateKey v_SIZE) (t_Slice u8) = + { + f_Error = Core.Array.t_TryFromSliceError; +- f_try_from_pre = (fun (value: t_Slice u8) -> true); +- f_try_from_post +- = +- (fun +- (value: t_Slice u8) +- (out: Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError) +- -> +- true); + f_try_from + = + fun (value: t_Slice u8) -> + match Core.Convert.f_try_into value with + | Core.Result.Result_Ok value -> +- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPrivateKey v_SIZE) ++ Core.Result.Result_Ok ({ f_value = value } <: t_KyberPrivateKey v_SIZE) <: - t_Slice u8) - in -- lemma_slice_append to_hash decrypted ind_cpa_public_key_hash; -- assert (decrypted == Spec.Kyber.ind_cpa_decrypt p ind_cpa_secret_key ciphertext.f_value); -- assert (to_hash == concat decrypted ind_cpa_public_key_hash); - let hashed:t_Array u8 (sz 64) = - Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) - in -@@ -194,10 +159,6 @@ - Core.Slice.impl__split_at (Rust_primitives.unsize hashed <: t_Slice u8) - Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE - in -- assert ((shared_secret,pseudorandomness) == split hashed Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE); -- assert (length implicit_rejection_value = v_SECRET_KEY_SIZE -! v_CPA_SECRET_KEY_SIZE -! v_PUBLIC_KEY_SIZE -! Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE); -- assert (length implicit_rejection_value = Spec.Kyber.v_SHARED_SECRET_SIZE); -- assert (Spec.Kyber.v_SHARED_SECRET_SIZE <=. Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p); - let (to_hash: t_Array u8 v_IMPLICIT_REJECTION_HASH_INPUT_SIZE):t_Array u8 - v_IMPLICIT_REJECTION_HASH_INPUT_SIZE = - Libcrux.Kem.Kyber.Ind_cpa.into_padded_array v_IMPLICIT_REJECTION_HASH_INPUT_SIZE -@@ -219,14 +180,11 @@ +- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError ++ Core.Result.t_Result (t_KyberPrivateKey v_SIZE) Core.Array.t_TryFromSliceError + | Core.Result.Result_Err e -> + Core.Result.Result_Err e <: - t_Slice u8) - in -- lemma_slice_append to_hash implicit_rejection_value ciphertext.f_value; - let (implicit_rejection_shared_secret: t_Array u8 (sz 32)):t_Array u8 (sz 32) = - Libcrux.Kem.Kyber.Hash_functions.v_PRF (sz 32) (Rust_primitives.unsize to_hash <: t_Slice u8) - in -- assert (implicit_rejection_shared_secret == Spec.Kyber.v_J to_hash); -- assert (Seq.length ind_cpa_public_key == v v_PUBLIC_KEY_SIZE); - let expected_ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE -+ Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE - v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 - v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE ind_cpa_public_key decrypted - pseudorandomness -@@ -236,18 +194,16 @@ - (Core.Convert.f_as_ref ciphertext <: t_Slice u8) - (Rust_primitives.unsize expected_ciphertext <: t_Slice u8) - in -- let res = - Libcrux.Kem.Kyber.Constant_time_ops.select_shared_secret_in_constant_time shared_secret - (Rust_primitives.unsize implicit_rejection_shared_secret <: t_Slice u8) - selector -- in -- res +- Core.Result.t_Result (t_MlKemPrivateKey v_SIZE) Core.Array.t_TryFromSliceError ++ Core.Result.t_Result (t_KyberPrivateKey v_SIZE) Core.Array.t_TryFromSliceError + } + +-let impl_12__as_slice (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : t_Array u8 v_SIZE = ++let impl_12__as_slice (v_SIZE: usize) (self: t_KyberPrivateKey v_SIZE) : t_Array u8 v_SIZE = + self.f_value + +-let impl_12__len (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) : usize = v_SIZE ++let impl_12__len (v_SIZE: usize) (self: t_KyberPrivateKey v_SIZE) : usize = v_SIZE + +-let impl_12__split_at (v_SIZE: usize) (self: t_MlKemPrivateKey v_SIZE) (mid: usize) +- : Pure (t_Slice u8 & t_Slice u8) +- (requires (mid <=. v_SIZE)) +- (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = ++let impl_12__split_at (v_SIZE: usize) (self: t_KyberPrivateKey v_SIZE) (mid: usize) ++ : (t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid --let encapsulate #p -+let encapsulate - (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) -- (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) -- (randomness: t_Array u8 (sz 32)) = -+ (public_key: Libcrux.Kem.Kyber.Types.t_KyberPublicKey v_PUBLIC_KEY_SIZE) -+ (randomness: t_Array u8 (sz 32)) -+ = - let (to_hash: t_Array u8 (sz 64)):t_Array u8 (sz 64) = - Libcrux.Kem.Kyber.Ind_cpa.into_padded_array (sz 64) - (Rust_primitives.unsize randomness <: t_Slice u8) -@@ -278,10 +234,6 @@ - <: - t_Slice u8) - in -- assert (Seq.slice to_hash 0 (v Libcrux.Kem.Kyber.Constants.v_H_DIGEST_SIZE) == randomness); -- lemma_slice_append to_hash randomness (Spec.Kyber.v_H public_key.f_value); -- assert (to_hash == concat randomness (Spec.Kyber.v_H public_key.f_value)); - - let hashed:t_Array u8 (sz 64) = - Libcrux.Kem.Kyber.Hash_functions.v_G (Rust_primitives.unsize to_hash <: t_Slice u8) - in -@@ -290,7 +242,7 @@ - Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE - in - let ciphertext:t_Array u8 v_CIPHERTEXT_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.encrypt #p v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE -+ Libcrux.Kem.Kyber.Ind_cpa.encrypt v_K v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE - v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN - v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE - (Rust_primitives.unsize (Libcrux.Kem.Kyber.Types.impl_18__as_slice v_PUBLIC_KEY_SIZE -@@ -300,42 +252,23 @@ - <: - t_Slice u8) randomness pseudorandomness - in -- Core.Convert.f_into ciphertext, -- Core.Result.impl__unwrap (Core.Convert.f_try_into shared_secret -- <: -- Core.Result.t_Result (t_Array u8 (sz 32)) Core.Array.t_TryFromSliceError) -- <: -- (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - --#push-options "--z3rlimit 100" --let validate_public_key #p -- (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) -- (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) -- = -- let pk:t_Array Libcrux.Kem.Kyber.Arithmetic.wfPolynomialRingElement v_K = -- Libcrux.Kem.Kyber.Ind_cpa.deserialize_public_key #p v_K -- (public_key.[ { Core.Ops.Range.f_end = v_RANKED_BYTES_PER_RING_ELEMENT } -+ let shared_secret:t_Array u8 (sz 32) = -+ match Core.Convert.f_try_into shared_secret with -+ | Core.Result.Result_Ok shared_secret -> shared_secret -+ | Core.Result.Result_Err _ -> -+ Rust_primitives.Hax.never_to_any (Core.Panicking.panic "explicit panic" - <: -- Core.Ops.Range.t_RangeTo usize ]) -+ Rust_primitives.Hax.t_Never) - in -- let public_key_serialized:t_Array u8 v_PUBLIC_KEY_SIZE = -- Libcrux.Kem.Kyber.Ind_cpa.serialize_public_key #p v_K -- v_RANKED_BYTES_PER_RING_ELEMENT -- v_PUBLIC_KEY_SIZE -- pk -- (public_key.[ { Core.Ops.Range.f_start = v_RANKED_BYTES_PER_RING_ELEMENT } -- <: -- Core.Ops.Range.t_RangeFrom usize ] -- <: -- t_Slice u8) -- in -- public_key =. public_key_serialized --#pop-options -+ Core.Convert.f_into ciphertext, shared_secret -+ <: -+ (Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) - --let generate_keypair #p -+let generate_keypair - (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) -- (randomness: t_Array u8 (sz 64)) = -+ (randomness: t_Array u8 (sz 64)) -+ = - let ind_cpa_keypair_randomness:t_Slice u8 = - randomness.[ { - Core.Ops.Range.f_start = sz 0; -@@ -353,7 +286,7 @@ - in - let ind_cpa_private_key, public_key:(t_Array u8 v_CPA_PRIVATE_KEY_SIZE & - t_Array u8 v_PUBLIC_KEY_SIZE) = -- Libcrux.Kem.Kyber.Ind_cpa.generate_keypair #p v_K -+ Libcrux.Kem.Kyber.Ind_cpa.generate_keypair v_K - v_CPA_PRIVATE_KEY_SIZE - v_PUBLIC_KEY_SIZE - v_BYTES_PER_RING_ELEMENT -@@ -362,17 +295,16 @@ - ind_cpa_keypair_randomness - in - let secret_key_serialized:t_Array u8 v_PRIVATE_KEY_SIZE = -- serialize_kem_secret_key #p v_PRIVATE_KEY_SIZE -+ serialize_kem_secret_key v_PRIVATE_KEY_SIZE - (Rust_primitives.unsize ind_cpa_private_key <: t_Slice u8) - (Rust_primitives.unsize public_key <: t_Slice u8) - implicit_rejection_value - in -- let (private_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_PRIVATE_KEY_SIZE):Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey -+ let (private_key: Libcrux.Kem.Kyber.Types.t_KyberPrivateKey v_PRIVATE_KEY_SIZE):Libcrux.Kem.Kyber.Types.t_KyberPrivateKey - v_PRIVATE_KEY_SIZE = - Core.Convert.f_from secret_key_serialized - in - Libcrux.Kem.Kyber.Types.impl__from v_PRIVATE_KEY_SIZE - v_PUBLIC_KEY_SIZE - private_key -- (Core.Convert.f_into public_key <: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) - -+ (Core.Convert.f_into public_key <: Libcrux.Kem.Kyber.Types.t_KyberPublicKey v_PUBLIC_KEY_SIZE) -diff -ruN extraction-edited/Libcrux.Kem.Kyber.fsti extraction-secret-independent/Libcrux.Kem.Kyber.fsti ---- extraction-edited/Libcrux.Kem.Kyber.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux.Kem.Kyber.fsti 2024-05-07 18:38:45 -@@ -4,90 +4,37 @@ - open FStar.Mul +- +- +- +- +- +- +- +-type t_MlKemPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } ++type t_KyberPublicKey (v_SIZE: usize) = { f_value:t_Array u8 v_SIZE } - unfold --let t_MlKemSharedSecret = t_Array u8 (sz 32) -+let t_KyberSharedSecret = t_Array u8 (sz 32) + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_13 (v_SIZE: usize) : Core.Convert.t_AsRef (t_MlKemPublicKey v_SIZE) (t_Slice u8) = +- { +- f_as_ref_pre = (fun (self: t_MlKemPublicKey v_SIZE) -> true); +- f_as_ref_post = (fun (self: t_MlKemPublicKey v_SIZE) (out: t_Slice u8) -> true); +- f_as_ref = fun (self: t_MlKemPublicKey v_SIZE) -> Rust_primitives.unsize self.f_value +- } ++let impl_13 (v_SIZE: usize) : Core.Convert.t_AsRef (t_KyberPublicKey v_SIZE) (t_Slice u8) = ++ { f_as_ref = fun (self: t_KyberPublicKey v_SIZE) -> Rust_primitives.unsize self.f_value } - let v_KEY_GENERATION_SEED_SIZE: usize = - Libcrux.Kem.Kyber.Constants.v_CPA_PKE_KEY_GENERATION_SEED_SIZE +! - Libcrux.Kem.Kyber.Constants.v_SHARED_SECRET_SIZE + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_14 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = +- { +- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); +- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPublicKey v_SIZE) -> true); +- f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_MlKemPublicKey v_SIZE +- } ++let impl_14 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPublicKey v_SIZE) (t_Array u8 v_SIZE) = ++ { f_from = fun (value: t_Array u8 v_SIZE) -> { f_value = value } <: t_KyberPublicKey v_SIZE } --val serialize_kem_secret_key (#p:Spec.Kyber.params) -+val serialize_kem_secret_key - (v_SERIALIZED_KEY_LEN: usize) - (private_key public_key implicit_rejection_value: t_Slice u8) -- : Pure (t_Array u8 v_SERIALIZED_KEY_LEN) -- (requires (length private_key == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -- length public_key == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -- length implicit_rejection_value == Spec.Kyber.v_SHARED_SECRET_SIZE /\ -- v_SERIALIZED_KEY_LEN == Spec.Kyber.v_SECRET_KEY_SIZE p)) -- (ensures (fun res -> res == -- Seq.append private_key ( -- Seq.append public_key ( -- Seq.append (Libcrux.Kem.Kyber.Hash_functions.v_H public_key) implicit_rejection_value)))) -+ : Prims.Pure (t_Array u8 v_SERIALIZED_KEY_LEN) Prims.l_True (fun _ -> Prims.l_True) + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_15 (v_SIZE: usize) : Core.Convert.t_From (t_MlKemPublicKey v_SIZE) (t_Array u8 v_SIZE) = ++let impl_15 (v_SIZE: usize) : Core.Convert.t_From (t_KyberPublicKey v_SIZE) (t_Array u8 v_SIZE) = + { +- f_from_pre = (fun (value: t_Array u8 v_SIZE) -> true); +- f_from_post = (fun (value: t_Array u8 v_SIZE) (out: t_MlKemPublicKey v_SIZE) -> true); + f_from + = + fun (value: t_Array u8 v_SIZE) -> +- { f_value = Core.Clone.f_clone value } <: t_MlKemPublicKey v_SIZE ++ { f_value = Core.Clone.f_clone value } <: t_KyberPublicKey v_SIZE + } --val decapsulate (#p:Spec.Kyber.params) -+val decapsulate - (v_K v_SECRET_KEY_SIZE v_CPA_SECRET_KEY_SIZE v_PUBLIC_KEY_SIZE v_CIPHERTEXT_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_C1_BLOCK_SIZE v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE v_IMPLICIT_REJECTION_HASH_INPUT_SIZE: - usize) -- (secret_key: Libcrux.Kem.Kyber.Types.t_MlKemPrivateKey v_SECRET_KEY_SIZE) -- (ciphertext: Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE) -- : Pure (t_Array u8 (sz 32)) -- (requires ( p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ -- Spec.Kyber.valid_params p /\ -- v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -- v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ -- v_IMPLICIT_REJECTION_HASH_INPUT_SIZE == Spec.Kyber.v_IMPLICIT_REJECTION_HASH_INPUT_SIZE p /\ -- v_SECRET_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ -- v_CPA_SECRET_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -- v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -- v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ -- v_C1_BLOCK_SIZE == Spec.Kyber.v_C1_BLOCK_SIZE p /\ -- v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ -- v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p -- )) -- (ensures (fun res -> -- res == Spec.Kyber.ind_cca_decapsulate p secret_key.f_value ciphertext.f_value)) -+ (secret_key: Libcrux.Kem.Kyber.Types.t_KyberPrivateKey v_SECRET_KEY_SIZE) -+ (ciphertext: Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE) -+ : Prims.Pure (t_Array u8 (sz 32)) Prims.l_True (fun _ -> Prims.l_True) + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_MlKemPublicKey v_SIZE) = +- { +- f_from_pre = (fun (value: t_MlKemPublicKey v_SIZE) -> true); +- f_from_post = (fun (value: t_MlKemPublicKey v_SIZE) (out: t_Array u8 v_SIZE) -> true); +- f_from = fun (value: t_MlKemPublicKey v_SIZE) -> value.f_value +- } ++let impl_16 (v_SIZE: usize) : Core.Convert.t_From (t_Array u8 v_SIZE) (t_KyberPublicKey v_SIZE) = ++ { f_from = fun (value: t_KyberPublicKey v_SIZE) -> value.f_value } --val encapsulate (#p:Spec.Kyber.params) -+val encapsulate - (v_K v_CIPHERTEXT_SIZE v_PUBLIC_KEY_SIZE v_T_AS_NTT_ENCODED_SIZE v_C1_SIZE v_C2_SIZE v_VECTOR_U_COMPRESSION_FACTOR v_VECTOR_V_COMPRESSION_FACTOR v_VECTOR_U_BLOCK_LEN v_ETA1 v_ETA1_RANDOMNESS_SIZE v_ETA2 v_ETA2_RANDOMNESS_SIZE: - usize) -- (public_key: Libcrux.Kem.Kyber.Types.t_MlKemPublicKey v_PUBLIC_KEY_SIZE) -+ (public_key: Libcrux.Kem.Kyber.Types.t_KyberPublicKey v_PUBLIC_KEY_SIZE) - (randomness: t_Array u8 (sz 32)) -- : Pure (Libcrux.Kem.Kyber.Types.t_MlKemCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) -- (requires (p == (let open Spec.Kyber in {v_RANK = v_K; v_ETA1; v_ETA2; v_VECTOR_U_COMPRESSION_FACTOR; v_VECTOR_V_COMPRESSION_FACTOR}) /\ -- Spec.Kyber.valid_params p /\ -- v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -- v_ETA2_RANDOMNESS_SIZE == Spec.Kyber.v_ETA2_RANDOMNESS_SIZE p /\ -- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -- v_CIPHERTEXT_SIZE == Spec.Kyber.v_CPA_PKE_CIPHERTEXT_SIZE p /\ -- v_C1_SIZE == Spec.Kyber.v_C1_SIZE p /\ -- v_C2_SIZE == Spec.Kyber.v_C2_SIZE p /\ -- v_T_AS_NTT_ENCODED_SIZE = Spec.Kyber.v_T_AS_NTT_ENCODED_SIZE p /\ -- v_VECTOR_U_BLOCK_LEN == Spec.Kyber.v_C1_BLOCK_SIZE p -- )) -+ : Prims.Pure (Libcrux.Kem.Kyber.Types.t_KyberCiphertext v_CIPHERTEXT_SIZE & t_Array u8 (sz 32)) -+ Prims.l_True -+ (fun _ -> Prims.l_True) + [@@ FStar.Tactics.Typeclasses.tcinstance] +-let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_MlKemPublicKey v_SIZE) (t_Slice u8) = ++let impl_17 (v_SIZE: usize) : Core.Convert.t_TryFrom (t_KyberPublicKey v_SIZE) (t_Slice u8) = + { + f_Error = Core.Array.t_TryFromSliceError; +- f_try_from_pre = (fun (value: t_Slice u8) -> true); +- f_try_from_post +- = +- (fun +- (value: t_Slice u8) +- (out: Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError) +- -> +- true); + f_try_from + = + fun (value: t_Slice u8) -> + match Core.Convert.f_try_into value with + | Core.Result.Result_Ok value -> +- Core.Result.Result_Ok ({ f_value = value } <: t_MlKemPublicKey v_SIZE) ++ Core.Result.Result_Ok ({ f_value = value } <: t_KyberPublicKey v_SIZE) + <: +- Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError ++ Core.Result.t_Result (t_KyberPublicKey v_SIZE) Core.Array.t_TryFromSliceError + | Core.Result.Result_Err e -> + Core.Result.Result_Err e + <: +- Core.Result.t_Result (t_MlKemPublicKey v_SIZE) Core.Array.t_TryFromSliceError ++ Core.Result.t_Result (t_KyberPublicKey v_SIZE) Core.Array.t_TryFromSliceError + } -- (ensures (fun (ct,ss) -> -- (ct.f_value,ss) == Spec.Kyber.ind_cca_encapsulate p public_key.f_value randomness)) -- --val validate_public_key (#p:Spec.Kyber.params) -- (v_K v_RANKED_BYTES_PER_RING_ELEMENT v_PUBLIC_KEY_SIZE: usize) -- (public_key: t_Array u8 v_PUBLIC_KEY_SIZE) -- : Prims.Pure bool -- (requires (v_K == p.v_RANK /\ -- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -- v_RANKED_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p -- )) -- (ensures (fun _ -> Prims.l_True)) -- --val generate_keypair (#p:Spec.Kyber.params) -+val generate_keypair - (v_K v_CPA_PRIVATE_KEY_SIZE v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE v_BYTES_PER_RING_ELEMENT v_ETA1 v_ETA1_RANDOMNESS_SIZE: - usize) - (randomness: t_Array u8 (sz 64)) -- : Pure (Libcrux.Kem.Kyber.Types.t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -- (requires (v_K == p.v_RANK /\ v_ETA1 == p.v_ETA1 /\ -- v_ETA1_RANDOMNESS_SIZE == Spec.Kyber.v_ETA1_RANDOMNESS_SIZE p /\ -- v_PUBLIC_KEY_SIZE == Spec.Kyber.v_CPA_PKE_PUBLIC_KEY_SIZE p /\ -- v_CPA_PRIVATE_KEY_SIZE == Spec.Kyber.v_CPA_PKE_SECRET_KEY_SIZE p /\ -- v_PRIVATE_KEY_SIZE == Spec.Kyber.v_SECRET_KEY_SIZE p /\ -- v_BYTES_PER_RING_ELEMENT == Spec.Kyber.v_RANKED_BYTES_PER_RING_ELEMENT p -- )) -- (ensures (fun kp -> -- (kp.f_sk.f_value,kp.f_pk.f_value) == Spec.Kyber.ind_cca_generate_keypair p randomness)) -+ : Prims.Pure (Libcrux.Kem.Kyber.Types.t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) -+ Prims.l_True -+ (fun _ -> Prims.l_True) +-let impl_18__as_slice (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : t_Array u8 v_SIZE = ++let impl_18__as_slice (v_SIZE: usize) (self: t_KyberPublicKey v_SIZE) : t_Array u8 v_SIZE = + self.f_value + +-let impl_18__len (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) : usize = v_SIZE ++let impl_18__len (v_SIZE: usize) (self: t_KyberPublicKey v_SIZE) : usize = v_SIZE + +-let impl_18__split_at (v_SIZE: usize) (self: t_MlKemPublicKey v_SIZE) (mid: usize) +- : Pure (t_Slice u8 & t_Slice u8) +- (requires (mid <=. v_SIZE)) +- (ensures (fun (x,y) -> Seq.length x == v mid /\ Seq.length y == v (v_SIZE -! mid))) = ++let impl_18__split_at (v_SIZE: usize) (self: t_KyberPublicKey v_SIZE) (mid: usize) ++ : (t_Slice u8 & t_Slice u8) = + Core.Slice.impl__split_at (Rust_primitives.unsize self.f_value <: t_Slice u8) mid + +-type t_MlKemKeyPair (v_PRIVATE_KEY_SIZE: usize) (v_PUBLIC_KEY_SIZE: usize) = { +- f_sk:t_MlKemPrivateKey v_PRIVATE_KEY_SIZE; +- f_pk:t_MlKemPublicKey v_PUBLIC_KEY_SIZE ++type t_KyberKeyPair (v_PRIVATE_KEY_SIZE: usize) (v_PUBLIC_KEY_SIZE: usize) = { ++ f_sk:t_KyberPrivateKey v_PRIVATE_KEY_SIZE; ++ f_pk:t_KyberPublicKey v_PUBLIC_KEY_SIZE + } + + let impl__from + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) +- (sk: t_MlKemPrivateKey v_PRIVATE_KEY_SIZE) +- (pk: t_MlKemPublicKey v_PUBLIC_KEY_SIZE) +- : t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = +- { f_sk = sk; f_pk = pk } <: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE ++ (sk: t_KyberPrivateKey v_PRIVATE_KEY_SIZE) ++ (pk: t_KyberPublicKey v_PUBLIC_KEY_SIZE) ++ : t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = ++ { f_sk = sk; f_pk = pk } <: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE + + let impl__new + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) + (sk: t_Array u8 v_PRIVATE_KEY_SIZE) + (pk: t_Array u8 v_PUBLIC_KEY_SIZE) +- : t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = ++ : t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE = + { f_sk = Core.Convert.f_into sk; f_pk = Core.Convert.f_into pk } + <: +- t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE ++ t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE + + let impl__pk + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) +- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) ++ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) + : t_Array u8 v_PUBLIC_KEY_SIZE = impl_18__as_slice v_PUBLIC_KEY_SIZE self.f_pk + + let impl__private_key + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) +- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) +- : t_MlKemPrivateKey v_PRIVATE_KEY_SIZE = self.f_sk ++ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) ++ : t_KyberPrivateKey v_PRIVATE_KEY_SIZE = self.f_sk + + let impl__public_key + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) +- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) +- : t_MlKemPublicKey v_PUBLIC_KEY_SIZE = self.f_pk ++ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) ++ : t_KyberPublicKey v_PUBLIC_KEY_SIZE = self.f_pk + + let impl__sk + (v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE: usize) +- (self: t_MlKemKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) ++ (self: t_KyberKeyPair v_PRIVATE_KEY_SIZE v_PUBLIC_KEY_SIZE) + : t_Array u8 v_PRIVATE_KEY_SIZE = impl_12__as_slice v_PRIVATE_KEY_SIZE self.f_sk +diff -ruN extraction-edited/Libcrux_platform.fsti extraction-secret-independent/Libcrux_platform.fsti +--- extraction-edited/Libcrux_platform.fsti 1970-01-01 01:00:00.000000000 +0100 ++++ extraction-secret-independent/Libcrux_platform.fsti 2024-05-14 15:56:45.502355236 +0200 +@@ -0,0 +1,4 @@ ++module Libcrux_platform ++#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" ++ ++val simd256_support : unit -> bool diff -ruN extraction-edited/Libcrux_platform.Platform.fsti extraction-secret-independent/Libcrux_platform.Platform.fsti ---- extraction-edited/Libcrux_platform.Platform.fsti 2024-05-07 18:38:45 -+++ extraction-secret-independent/Libcrux_platform.Platform.fsti 1970-01-01 01:00:00 +--- extraction-edited/Libcrux_platform.Platform.fsti 2024-05-14 15:56:45.421356565 +0200 ++++ extraction-secret-independent/Libcrux_platform.Platform.fsti 1970-01-01 01:00:00.000000000 +0100 @@ -1,20 +0,0 @@ -module Libcrux_platform.Platform -#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" @@ -8123,17 +8164,9 @@ diff -ruN extraction-edited/Libcrux_platform.Platform.fsti extraction-secret-ind -val sha256_support: Prims.unit -> Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) - -val simd128_support: Prims.unit -> Prims.Pure bool Prims.l_True (fun _ -> Prims.l_True) -diff -ruN extraction-edited/Libcrux_platform.fsti extraction-secret-independent/Libcrux_platform.fsti ---- extraction-edited/Libcrux_platform.fsti 1970-01-01 01:00:00 -+++ extraction-secret-independent/Libcrux_platform.fsti 2024-05-07 18:38:46 -@@ -0,0 +1,4 @@ -+module Libcrux_platform -+#set-options "--fuel 0 --ifuel 1 --z3rlimit 15" -+ -+val simd256_support : unit -> bool diff -ruN extraction-edited/MkSeq.fst extraction-secret-independent/MkSeq.fst ---- extraction-edited/MkSeq.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/MkSeq.fst 1970-01-01 01:00:00 +--- extraction-edited/MkSeq.fst 2024-05-14 15:56:45.438356286 +0200 ++++ extraction-secret-independent/MkSeq.fst 1970-01-01 01:00:00.000000000 +0100 @@ -1,91 +0,0 @@ -module MkSeq -open Core @@ -8227,8 +8260,8 @@ diff -ruN extraction-edited/MkSeq.fst extraction-secret-independent/MkSeq.fst - -%splice[] (init 13 (fun i -> create_gen_tac (i + 1))) diff -ruN extraction-edited/Spec.Kyber.fst extraction-secret-independent/Spec.Kyber.fst ---- extraction-edited/Spec.Kyber.fst 2024-05-07 18:38:45 -+++ extraction-secret-independent/Spec.Kyber.fst 1970-01-01 01:00:00 +--- extraction-edited/Spec.Kyber.fst 2024-05-14 15:56:45.430356417 +0200 ++++ extraction-secret-independent/Spec.Kyber.fst 1970-01-01 01:00:00.000000000 +0100 @@ -1,435 +0,0 @@ -module Spec.Kyber -#set-options "--fuel 0 --ifuel 1 --z3rlimit 100" diff --git a/proofs/fstar/extraction/Libcrux.Digest.Incremental_x4.fsti b/proofs/fstar/extraction/Libcrux.Digest.Incremental_x4.fsti index 935c9e025..86c3e76b5 100644 --- a/proofs/fstar/extraction/Libcrux.Digest.Incremental_x4.fsti +++ b/proofs/fstar/extraction/Libcrux.Digest.Incremental_x4.fsti @@ -4,7 +4,7 @@ open Core open FStar.Mul /// Incremental state -val t_Shake128StateX4:Type +val t_Shake128StateX4:Type0 /// Absorb up to 4 blocks. /// The `input` must be of length 1 to 4.