/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 | | |