Coverage Report

Created: 2025-07-12 06:44

/src/liboqs/src/kem/bike/additional_r4/sampling.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
 * SPDX-License-Identifier: Apache-2.0"
3
 *
4
 * Written by Nir Drucker, Shay Gueron and Dusan Kostic,
5
 * AWS Cryptographic Algorithms Group.
6
 */
7
8
#include <assert.h>
9
10
#include "cleanup.h"
11
#include "sampling.h"
12
#include "prf_internal.h"
13
#include "sampling_internal.h"
14
#include <oqs/rand.h>
15
16
void get_seeds(OUT seeds_t *seeds)
17
0
{
18
0
  OQS_randombytes((uint8_t *)seeds, NUM_OF_SEEDS * sizeof(seed_t));
19
20
0
  for(uint32_t i = 0; i < NUM_OF_SEEDS; ++i) {
21
0
    print("s: ", (uint64_t *)&seeds->seed[i], SIZEOF_BITS(seed_t));
22
0
  }
23
0
}
Unexecuted instantiation: OQS_KEM_bike_l1_get_seeds
Unexecuted instantiation: OQS_KEM_bike_l3_get_seeds
Unexecuted instantiation: OQS_KEM_bike_l5_get_seeds
24
25
_INLINE_ void make_odd_weight(IN OUT r_t *r)
26
0
{
27
0
  if(((r_bits_vector_weight(r) % 2) == 1)) {
28
    // Already odd
29
0
    return;
30
0
  }
31
32
0
  r->raw[0] ^= 1;
33
0
}
34
35
// Returns an array of r pseudorandom bits.
36
// No restrictions exist for the top or bottom bits.
37
// If the generation requires an odd number, then set must_be_odd=1.
38
// The function uses the provided prf context.
39
ret_t sample_uniform_r_bits_with_fixed_prf_context(
40
  OUT r_t *r,
41
  IN OUT prf_state_t *prf_state,
42
  IN const must_be_odd_t      must_be_odd)
43
0
{
44
  // Generate random data
45
0
  GUARD(get_prf_output(r->raw, prf_state, R_BYTES));
46
47
  // Mask upper bits of the MSByte
48
0
  r->raw[R_BYTES - 1] &= MASK(R_BITS + 8 - (R_BYTES * 8));
49
50
0
  if(must_be_odd == MUST_BE_ODD) {
51
0
    make_odd_weight(r);
52
0
  }
53
54
0
  return SUCCESS;
55
0
}
Unexecuted instantiation: OQS_KEM_bike_l1_sample_uniform_r_bits_with_fixed_prf_context
Unexecuted instantiation: OQS_KEM_bike_l3_sample_uniform_r_bits_with_fixed_prf_context
Unexecuted instantiation: OQS_KEM_bike_l5_sample_uniform_r_bits_with_fixed_prf_context
56
57
ret_t sample_indices_fisher_yates(OUT idx_t *out,
58
                                  IN  size_t num_indices,
59
                                  IN  idx_t max_idx_val,
60
0
                                  IN OUT prf_state_t *prf_state) {
61
62
0
    for (size_t i = num_indices; i-- > 0;) {
63
0
#define CWW_RAND_BYTES 4
64
0
        uint64_t rand = 0ULL;
65
0
        GUARD(get_prf_output((uint8_t *)&rand, prf_state, CWW_RAND_BYTES));
66
0
        rand *= (max_idx_val - i);
67
68
    // new index l is such that i <= l < max_idx_val
69
0
        uint32_t l = i + (uint32_t)(rand >> (CWW_RAND_BYTES * 8));
70
71
    // Loop over (the end of) the output array to determine if l is a duplicate
72
0
        uint32_t is_dup = 0;
73
0
        for (size_t j = i + 1; j < num_indices; ++j) {
74
0
            is_dup |= secure_cmp32(l, out[j]);
75
0
        }
76
77
    // if l is a duplicate out[i] gets i else out[i] gets l
78
    // mask is all 1 if l is a duplicate, all 0 else
79
0
        uint32_t mask = -is_dup;
80
0
        out[i] = (mask & i) ^ (~mask & l);
81
0
    }
82
83
0
    return SUCCESS;
84
0
}
Unexecuted instantiation: OQS_KEM_bike_l1_sample_indices_fisher_yates
Unexecuted instantiation: OQS_KEM_bike_l3_sample_indices_fisher_yates
Unexecuted instantiation: OQS_KEM_bike_l5_sample_indices_fisher_yates
85
86
_INLINE_ ret_t generate_sparse_rep_for_sk(OUT pad_r_t *r,
87
                                          OUT idx_t *wlist,
88
                                          IN OUT prf_state_t *prf_state,
89
                                          IN sampling_ctx *ctx)
90
0
{
91
0
  idx_t wlist_temp[D] = {0};
92
93
0
  GUARD(sample_indices_fisher_yates(wlist_temp, D, R_BITS, prf_state));
94
95
0
  bike_memcpy(wlist, wlist_temp, D * sizeof(idx_t));
96
0
  ctx->secure_set_bits(r, 0, wlist, D);
97
98
0
  secure_clean((uint8_t *)wlist_temp, sizeof(*wlist_temp));
99
0
  return SUCCESS;
100
0
}
Unexecuted instantiation: sampling.c:OQS_KEM_bike_l1_generate_sparse_rep_for_sk
Unexecuted instantiation: sampling.c:OQS_KEM_bike_l3_generate_sparse_rep_for_sk
Unexecuted instantiation: sampling.c:OQS_KEM_bike_l5_generate_sparse_rep_for_sk
101
102
ret_t generate_secret_key(OUT pad_r_t *h0, OUT pad_r_t *h1,
103
                          OUT idx_t *h0_wlist, OUT idx_t *h1_wlist,
104
                          IN const seed_t *seed)
105
0
{
106
  // Initialize the sampling context.
107
0
  sampling_ctx ctx = {0};
108
0
  sampling_ctx_init(&ctx);
109
110
0
  DEFER_CLEANUP(prf_state_t prf_state = {0}, clean_prf_state);
111
112
0
  GUARD(init_prf_state(&prf_state, MAX_PRF_INVOCATION, seed));
113
114
0
  GUARD(generate_sparse_rep_for_sk(h0, h0_wlist, &prf_state, &ctx));
115
0
  GUARD(generate_sparse_rep_for_sk(h1, h1_wlist, &prf_state, &ctx));
116
117
0
  return SUCCESS;
118
0
}
Unexecuted instantiation: OQS_KEM_bike_l1_generate_secret_key
Unexecuted instantiation: OQS_KEM_bike_l3_generate_secret_key
Unexecuted instantiation: OQS_KEM_bike_l5_generate_secret_key
119
120
ret_t generate_error_vector(OUT pad_e_t *e, IN const seed_t *seed)
121
0
{
122
  // Initialize the sampling context.
123
0
  sampling_ctx ctx;
124
0
  sampling_ctx_init(&ctx);
125
126
0
  DEFER_CLEANUP(prf_state_t prf_state = {0}, clean_prf_state);
127
128
0
  GUARD(init_prf_state(&prf_state, MAX_PRF_INVOCATION, seed));
129
130
0
  idx_t wlist[T];
131
0
  GUARD(sample_indices_fisher_yates(wlist, T, N_BITS, &prf_state));
132
133
  // (e0, e1) hold bits 0..R_BITS-1 and R_BITS..2*R_BITS-1 of the error, resp.
134
0
  ctx.secure_set_bits(&e->val[0], 0, wlist, T);
135
0
  ctx.secure_set_bits(&e->val[1], R_BITS, wlist, T);
136
137
  // Clean the padding of the elements.
138
0
  PE0_RAW(e)[R_BYTES - 1] &= LAST_R_BYTE_MASK;
139
0
  PE1_RAW(e)[R_BYTES - 1] &= LAST_R_BYTE_MASK;
140
0
  bike_memset(&PE0_RAW(e)[R_BYTES], 0, R_PADDED_BYTES - R_BYTES);
141
0
  bike_memset(&PE1_RAW(e)[R_BYTES], 0, R_PADDED_BYTES - R_BYTES);
142
143
0
  secure_clean((uint8_t *)wlist, sizeof(*wlist));
144
145
0
  return SUCCESS;
146
0
}
Unexecuted instantiation: OQS_KEM_bike_l1_generate_error_vector
Unexecuted instantiation: OQS_KEM_bike_l3_generate_error_vector
Unexecuted instantiation: OQS_KEM_bike_l5_generate_error_vector
147
148
// Returns an array of r pseudorandom bits.
149
// No restrictions exist for the top or bottom bits.
150
// If the generation requires an odd number, then set must_be_odd = MUST_BE_ODD
151
ret_t sample_uniform_r_bits(OUT r_t *r,
152
                            IN const seed_t *      seed,
153
                            IN const must_be_odd_t must_be_odd)
154
0
{
155
  // For the seedexpander
156
0
  DEFER_CLEANUP(prf_state_t prf_state = {0}, clean_prf_state);
157
158
0
  GUARD(init_prf_state(&prf_state, MAX_PRF_INVOCATION, seed));
159
160
0
  GUARD(sample_uniform_r_bits_with_fixed_prf_context(r, &prf_state, must_be_odd));
161
162
0
  return SUCCESS;
163
0
}
Unexecuted instantiation: OQS_KEM_bike_l1_sample_uniform_r_bits
Unexecuted instantiation: OQS_KEM_bike_l3_sample_uniform_r_bits
Unexecuted instantiation: OQS_KEM_bike_l5_sample_uniform_r_bits
164