@@ -38,17 +38,11 @@ void mld_pack_pk(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
3838
3939#if !defined(MLD_CONFIG_NO_VERIFY_API )
4040MLD_INTERNAL_API
41- void mld_unpack_pk_t1 (mld_polyveck * t1 ,
42- const uint8_t pk [MLDSA_CRYPTO_PUBLICKEYBYTES ])
41+ void mld_unpack_pk_t1 (mld_poly * t1 ,
42+ const uint8_t pk [MLDSA_CRYPTO_PUBLICKEYBYTES ],
43+ unsigned int i )
4344{
44- unsigned int i ;
45-
46- pk += MLDSA_SEEDBYTES ;
47-
48- for (i = 0 ; i < MLDSA_K ; ++ i )
49- {
50- mld_polyt1_unpack (& t1 -> vec [i ], pk + i * MLDSA_POLYT1_PACKEDBYTES );
51- }
45+ mld_polyt1_unpack (t1 , pk + MLDSA_SEEDBYTES + i * MLDSA_POLYT1_PACKEDBYTES );
5246}
5347#endif /* !MLD_CONFIG_NO_VERIFY_API */
5448
@@ -172,75 +166,52 @@ void mld_pack_sig_z(uint8_t sig[MLDSA_CRYPTO_BYTES], const mld_poly *zi,
172166
173167#if !defined(MLD_CONFIG_NO_VERIFY_API )
174168MLD_INTERNAL_API
175- int mld_sig_unpack_hints (mld_polyveck * h , const uint8_t sig [MLDSA_CRYPTO_BYTES ])
169+ int mld_sig_unpack_hints (mld_poly * h , const uint8_t sig [MLDSA_CRYPTO_BYTES ],
170+ unsigned int i )
176171{
177172 const uint8_t * packed_hints =
178173 sig + MLDSA_CTILDEBYTES + MLDSA_L * MLDSA_POLYZ_PACKEDBYTES ;
179- unsigned int i , j ;
180- unsigned int old_hint_count ;
174+ const unsigned int old_hint_count =
175+ (i == 0 ) ? 0 : packed_hints [MLDSA_OMEGA + i - 1 ];
176+ const unsigned int new_hint_count = packed_hints [MLDSA_OMEGA + i ];
177+ unsigned int j ;
181178
182- /* Set all coefficients of all polynomials to 0. */
183- /* Only those that are actually non-zero hints will */
184- /* be overwritten below. */
185- mld_memset ( h , 0 , sizeof ( mld_polyveck ));
179+ if ( new_hint_count < old_hint_count || new_hint_count > MLDSA_OMEGA )
180+ {
181+ return MLD_ERR_FAIL ;
182+ }
186183
187- old_hint_count = 0 ;
188- for (i = 0 ; i < MLDSA_K ; ++ i )
184+ mld_memset (h , 0 , sizeof (mld_poly ));
185+
186+ for (j = old_hint_count ; j < new_hint_count ; ++ j )
189187 __loop__ (
190- invariant (i <= MLDSA_K )
191- /* Maintain the post-condition */
192- invariant (forall ( k1 , 0 , MLDSA_K , array_bound (h -> vec [ k1 ]. coeffs , 0 , MLDSA_N , 0 , 2 ) ))
193- decreases (MLDSA_K - i )
188+ invariant (j >= old_hint_count && j <= new_hint_count &&
189+ new_hint_count <= MLDSA_OMEGA )
190+ invariant (array_bound (h -> coeffs , 0 , MLDSA_N , 0 , 2 ))
191+ decreases (new_hint_count - j )
194192 )
195193 {
196- /* Grab the hint count for the i'th polynomial */
197- const unsigned int new_hint_count = packed_hints [MLDSA_OMEGA + i ];
198-
199- /* new_hint_count must increase or stay the same, but also remain */
200- /* less than or equal to MLDSA_OMEGA */
201- if (new_hint_count < old_hint_count || new_hint_count > MLDSA_OMEGA )
194+ if (j > old_hint_count && packed_hints [j ] <= packed_hints [j - 1 ])
202195 {
203- /* Error - new_hint_count is invalid */
204- return 1 ;
196+ return MLD_ERR_FAIL ;
205197 }
198+ /* Safety: packed_hints[j] is uint8_t (<= 255) and MLDSA_N == 256. */
199+ h -> coeffs [packed_hints [j ]] = 1 ;
200+ }
206201
207- /* If new_hint_count == old_hint_count, then this polynomial has */
208- /* zero hints, so this loop executes zero times and we move */
209- /* straight on to the next polynomial. */
210- for (j = old_hint_count ; j < new_hint_count ; ++ j )
202+ /* On the last row, also verify that the trailing index slots are zero. */
203+ if ( i == MLDSA_K - 1 )
204+ {
205+ for (j = new_hint_count ; j < MLDSA_OMEGA ; ++ j )
211206 __loop__ (
212- invariant (i <= MLDSA_K )
213- /* Maintain the post-condition */
214- invariant (j <= new_hint_count && new_hint_count <= MLDSA_OMEGA )
215- invariant (forall (k1 , 0 , MLDSA_K , array_bound (h -> vec [k1 ].coeffs , 0 , MLDSA_N , 0 , 2 )))
216- decreases (new_hint_count - j )
217- )
207+ invariant (j <= MLDSA_OMEGA )
208+ decreases (MLDSA_OMEGA - j )
209+ )
218210 {
219- const uint8_t this_hint_index = packed_hints [j ];
220-
221- /* Coefficients must be ordered for strong unforgeability */
222- if (j > old_hint_count && this_hint_index <= packed_hints [j - 1 ])
211+ if (packed_hints [j ] != 0 )
223212 {
224- return 1 ;
213+ return MLD_ERR_FAIL ;
225214 }
226- h -> vec [i ].coeffs [this_hint_index ] = 1 ;
227- }
228-
229- old_hint_count = new_hint_count ;
230- }
231-
232- /* Extra indices must be zero for strong unforgeability */
233- for (j = old_hint_count ; j < MLDSA_OMEGA ; ++ j )
234- __loop__ (
235- invariant (j <= MLDSA_OMEGA )
236- /* Maintain the post-condition */
237- invariant (forall (k1 , 0 , MLDSA_K , array_bound (h -> vec [k1 ].coeffs , 0 , MLDSA_N , 0 , 2 )))
238- decreases (MLDSA_OMEGA - j )
239- )
240- {
241- if (packed_hints [j ] != 0 )
242- {
243- return 1 ;
244215 }
245216 }
246217
0 commit comments