Coverage Report

Created: 2026-04-12 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/liboqs/src/kem/frodokem/external/util.c
Line
Count
Source
1
/********************************************************************************************
2
* FrodoKEM: Learning with Errors Key Encapsulation
3
*
4
* Abstract: additional functions for FrodoKEM
5
*********************************************************************************************/
6
7
#include <string.h>
8
9
6.10M
#define min(x, y) (((x) < (y)) ? (x) : (y))
10
11
12
void frodo_pack(unsigned char *out, const size_t outlen, const uint16_t *in, const size_t inlen, const unsigned char lsb) 
13
210
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
210
    memset(out, 0, outlen);
16
17
210
    size_t i = 0;            // whole bytes already filled in
18
210
    size_t j = 0;            // whole uint16_t already copied
19
210
    uint16_t w = 0;          // the leftover, not yet copied
20
210
    unsigned char bits = 0;  // the number of lsb in w
21
22
2.36M
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
2.36M
        unsigned char b = 0;  // bits in out[i] already filled in
35
4.81M
        while (b < 8) {
36
2.44M
            int nbits = min(8 - b, bits);
37
2.44M
            uint16_t mask = (1 << nbits) - 1;
38
2.44M
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
2.44M
            out[i] = out[i] + (t << (8 - b - nbits));
40
2.44M
            b += nbits;
41
2.44M
            bits -= nbits;
42
2.44M
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
2.44M
            if (bits == 0) {
45
1.19M
                if (j < inlen) {
46
1.19M
                    w = in[j];
47
1.19M
                    bits = lsb;
48
1.19M
                    j++;
49
1.19M
                } else {
50
210
                    break;  // the input vector is exhausted
51
210
                }
52
1.19M
            }
53
2.44M
        }
54
2.36M
        if (b == 8) {  // out[i] is filled in
55
2.36M
            i++;
56
2.36M
        }
57
2.36M
    }
58
210
}
oqs_kem_frodokem_640_aes_pack
Line
Count
Source
13
6
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
6
    memset(out, 0, outlen);
16
17
6
    size_t i = 0;            // whole bytes already filled in
18
6
    size_t j = 0;            // whole uint16_t already copied
19
6
    uint16_t w = 0;          // the leftover, not yet copied
20
6
    unsigned char bits = 0;  // the number of lsb in w
21
22
38.6k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
38.6k
        unsigned char b = 0;  // bits in out[i] already filled in
35
95.3k
        while (b < 8) {
36
56.6k
            int nbits = min(8 - b, bits);
37
56.6k
            uint16_t mask = (1 << nbits) - 1;
38
56.6k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
56.6k
            out[i] = out[i] + (t << (8 - b - nbits));
40
56.6k
            b += nbits;
41
56.6k
            bits -= nbits;
42
56.6k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
56.6k
            if (bits == 0) {
45
20.6k
                if (j < inlen) {
46
20.6k
                    w = in[j];
47
20.6k
                    bits = lsb;
48
20.6k
                    j++;
49
20.6k
                } else {
50
6
                    break;  // the input vector is exhausted
51
6
                }
52
20.6k
            }
53
56.6k
        }
54
38.6k
        if (b == 8) {  // out[i] is filled in
55
38.6k
            i++;
56
38.6k
        }
57
38.6k
    }
58
6
}
oqs_kem_frodokem_640_shake_pack
Line
Count
Source
13
6
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
6
    memset(out, 0, outlen);
16
17
6
    size_t i = 0;            // whole bytes already filled in
18
6
    size_t j = 0;            // whole uint16_t already copied
19
6
    uint16_t w = 0;          // the leftover, not yet copied
20
6
    unsigned char bits = 0;  // the number of lsb in w
21
22
38.6k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
38.6k
        unsigned char b = 0;  // bits in out[i] already filled in
35
95.3k
        while (b < 8) {
36
56.6k
            int nbits = min(8 - b, bits);
37
56.6k
            uint16_t mask = (1 << nbits) - 1;
38
56.6k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
56.6k
            out[i] = out[i] + (t << (8 - b - nbits));
40
56.6k
            b += nbits;
41
56.6k
            bits -= nbits;
42
56.6k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
56.6k
            if (bits == 0) {
45
20.6k
                if (j < inlen) {
46
20.6k
                    w = in[j];
47
20.6k
                    bits = lsb;
48
20.6k
                    j++;
49
20.6k
                } else {
50
6
                    break;  // the input vector is exhausted
51
6
                }
52
20.6k
            }
53
56.6k
        }
54
38.6k
        if (b == 8) {  // out[i] is filled in
55
38.6k
            i++;
56
38.6k
        }
57
38.6k
    }
58
6
}
oqs_kem_frodokem_976_aes_pack
Line
Count
Source
13
30
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
30
    memset(out, 0, outlen);
16
17
30
    size_t i = 0;            // whole bytes already filled in
18
30
    size_t j = 0;            // whole uint16_t already copied
19
30
    uint16_t w = 0;          // the leftover, not yet copied
20
30
    unsigned char bits = 0;  // the number of lsb in w
21
22
313k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
313k
        unsigned char b = 0;  // bits in out[i] already filled in
35
627k
        while (b < 8) {
36
313k
            int nbits = min(8 - b, bits);
37
313k
            uint16_t mask = (1 << nbits) - 1;
38
313k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
313k
            out[i] = out[i] + (t << (8 - b - nbits));
40
313k
            b += nbits;
41
313k
            bits -= nbits;
42
313k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
313k
            if (bits == 0) {
45
156k
                if (j < inlen) {
46
156k
                    w = in[j];
47
156k
                    bits = lsb;
48
156k
                    j++;
49
156k
                } else {
50
30
                    break;  // the input vector is exhausted
51
30
                }
52
156k
            }
53
313k
        }
54
313k
        if (b == 8) {  // out[i] is filled in
55
313k
            i++;
56
313k
        }
57
313k
    }
58
30
}
oqs_kem_frodokem_976_shake_pack
Line
Count
Source
13
33
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
33
    memset(out, 0, outlen);
16
17
33
    size_t i = 0;            // whole bytes already filled in
18
33
    size_t j = 0;            // whole uint16_t already copied
19
33
    uint16_t w = 0;          // the leftover, not yet copied
20
33
    unsigned char bits = 0;  // the number of lsb in w
21
22
344k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
344k
        unsigned char b = 0;  // bits in out[i] already filled in
35
689k
        while (b < 8) {
36
344k
            int nbits = min(8 - b, bits);
37
344k
            uint16_t mask = (1 << nbits) - 1;
38
344k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
344k
            out[i] = out[i] + (t << (8 - b - nbits));
40
344k
            b += nbits;
41
344k
            bits -= nbits;
42
344k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
344k
            if (bits == 0) {
45
172k
                if (j < inlen) {
46
172k
                    w = in[j];
47
172k
                    bits = lsb;
48
172k
                    j++;
49
172k
                } else {
50
33
                    break;  // the input vector is exhausted
51
33
                }
52
172k
            }
53
344k
        }
54
344k
        if (b == 8) {  // out[i] is filled in
55
344k
            i++;
56
344k
        }
57
344k
    }
58
33
}
oqs_kem_frodokem_1344_aes_pack
Line
Count
Source
13
15
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
15
    memset(out, 0, outlen);
16
17
15
    size_t i = 0;            // whole bytes already filled in
18
15
    size_t j = 0;            // whole uint16_t already copied
19
15
    uint16_t w = 0;          // the leftover, not yet copied
20
15
    unsigned char bits = 0;  // the number of lsb in w
21
22
215k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
215k
        unsigned char b = 0;  // bits in out[i] already filled in
35
431k
        while (b < 8) {
36
215k
            int nbits = min(8 - b, bits);
37
215k
            uint16_t mask = (1 << nbits) - 1;
38
215k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
215k
            out[i] = out[i] + (t << (8 - b - nbits));
40
215k
            b += nbits;
41
215k
            bits -= nbits;
42
215k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
215k
            if (bits == 0) {
45
107k
                if (j < inlen) {
46
107k
                    w = in[j];
47
107k
                    bits = lsb;
48
107k
                    j++;
49
107k
                } else {
50
15
                    break;  // the input vector is exhausted
51
15
                }
52
107k
            }
53
215k
        }
54
215k
        if (b == 8) {  // out[i] is filled in
55
215k
            i++;
56
215k
        }
57
215k
    }
58
15
}
oqs_kem_frodokem_1344_shake_pack
Line
Count
Source
13
9
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
9
    memset(out, 0, outlen);
16
17
9
    size_t i = 0;            // whole bytes already filled in
18
9
    size_t j = 0;            // whole uint16_t already copied
19
9
    uint16_t w = 0;          // the leftover, not yet copied
20
9
    unsigned char bits = 0;  // the number of lsb in w
21
22
129k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
129k
        unsigned char b = 0;  // bits in out[i] already filled in
35
258k
        while (b < 8) {
36
129k
            int nbits = min(8 - b, bits);
37
129k
            uint16_t mask = (1 << nbits) - 1;
38
129k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
129k
            out[i] = out[i] + (t << (8 - b - nbits));
40
129k
            b += nbits;
41
129k
            bits -= nbits;
42
129k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
129k
            if (bits == 0) {
45
64.7k
                if (j < inlen) {
46
64.7k
                    w = in[j];
47
64.7k
                    bits = lsb;
48
64.7k
                    j++;
49
64.7k
                } else {
50
9
                    break;  // the input vector is exhausted
51
9
                }
52
64.7k
            }
53
129k
        }
54
129k
        if (b == 8) {  // out[i] is filled in
55
129k
            i++;
56
129k
        }
57
129k
    }
58
9
}
oqs_kem_efrodokem_640_aes_pack
Line
Count
Source
13
9
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
9
    memset(out, 0, outlen);
16
17
9
    size_t i = 0;            // whole bytes already filled in
18
9
    size_t j = 0;            // whole uint16_t already copied
19
9
    uint16_t w = 0;          // the leftover, not yet copied
20
9
    unsigned char bits = 0;  // the number of lsb in w
21
22
57.9k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
57.9k
        unsigned char b = 0;  // bits in out[i] already filled in
35
142k
        while (b < 8) {
36
85.0k
            int nbits = min(8 - b, bits);
37
85.0k
            uint16_t mask = (1 << nbits) - 1;
38
85.0k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
85.0k
            out[i] = out[i] + (t << (8 - b - nbits));
40
85.0k
            b += nbits;
41
85.0k
            bits -= nbits;
42
85.0k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
85.0k
            if (bits == 0) {
45
30.9k
                if (j < inlen) {
46
30.9k
                    w = in[j];
47
30.9k
                    bits = lsb;
48
30.9k
                    j++;
49
30.9k
                } else {
50
9
                    break;  // the input vector is exhausted
51
9
                }
52
30.9k
            }
53
85.0k
        }
54
57.9k
        if (b == 8) {  // out[i] is filled in
55
57.9k
            i++;
56
57.9k
        }
57
57.9k
    }
58
9
}
oqs_kem_efrodokem_640_shake_pack
Line
Count
Source
13
3
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
3
    memset(out, 0, outlen);
16
17
3
    size_t i = 0;            // whole bytes already filled in
18
3
    size_t j = 0;            // whole uint16_t already copied
19
3
    uint16_t w = 0;          // the leftover, not yet copied
20
3
    unsigned char bits = 0;  // the number of lsb in w
21
22
19.3k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
19.3k
        unsigned char b = 0;  // bits in out[i] already filled in
35
47.6k
        while (b < 8) {
36
28.3k
            int nbits = min(8 - b, bits);
37
28.3k
            uint16_t mask = (1 << nbits) - 1;
38
28.3k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
28.3k
            out[i] = out[i] + (t << (8 - b - nbits));
40
28.3k
            b += nbits;
41
28.3k
            bits -= nbits;
42
28.3k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
28.3k
            if (bits == 0) {
45
10.3k
                if (j < inlen) {
46
10.3k
                    w = in[j];
47
10.3k
                    bits = lsb;
48
10.3k
                    j++;
49
10.3k
                } else {
50
3
                    break;  // the input vector is exhausted
51
3
                }
52
10.3k
            }
53
28.3k
        }
54
19.3k
        if (b == 8) {  // out[i] is filled in
55
19.3k
            i++;
56
19.3k
        }
57
19.3k
    }
58
3
}
oqs_kem_efrodokem_976_aes_pack
Line
Count
Source
13
27
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
27
    memset(out, 0, outlen);
16
17
27
    size_t i = 0;            // whole bytes already filled in
18
27
    size_t j = 0;            // whole uint16_t already copied
19
27
    uint16_t w = 0;          // the leftover, not yet copied
20
27
    unsigned char bits = 0;  // the number of lsb in w
21
22
282k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
282k
        unsigned char b = 0;  // bits in out[i] already filled in
35
564k
        while (b < 8) {
36
282k
            int nbits = min(8 - b, bits);
37
282k
            uint16_t mask = (1 << nbits) - 1;
38
282k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
282k
            out[i] = out[i] + (t << (8 - b - nbits));
40
282k
            b += nbits;
41
282k
            bits -= nbits;
42
282k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
282k
            if (bits == 0) {
45
141k
                if (j < inlen) {
46
141k
                    w = in[j];
47
141k
                    bits = lsb;
48
141k
                    j++;
49
141k
                } else {
50
27
                    break;  // the input vector is exhausted
51
27
                }
52
141k
            }
53
282k
        }
54
282k
        if (b == 8) {  // out[i] is filled in
55
282k
            i++;
56
282k
        }
57
282k
    }
58
27
}
oqs_kem_efrodokem_976_shake_pack
Line
Count
Source
13
27
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
27
    memset(out, 0, outlen);
16
17
27
    size_t i = 0;            // whole bytes already filled in
18
27
    size_t j = 0;            // whole uint16_t already copied
19
27
    uint16_t w = 0;          // the leftover, not yet copied
20
27
    unsigned char bits = 0;  // the number of lsb in w
21
22
282k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
282k
        unsigned char b = 0;  // bits in out[i] already filled in
35
564k
        while (b < 8) {
36
282k
            int nbits = min(8 - b, bits);
37
282k
            uint16_t mask = (1 << nbits) - 1;
38
282k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
282k
            out[i] = out[i] + (t << (8 - b - nbits));
40
282k
            b += nbits;
41
282k
            bits -= nbits;
42
282k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
282k
            if (bits == 0) {
45
141k
                if (j < inlen) {
46
141k
                    w = in[j];
47
141k
                    bits = lsb;
48
141k
                    j++;
49
141k
                } else {
50
27
                    break;  // the input vector is exhausted
51
27
                }
52
141k
            }
53
282k
        }
54
282k
        if (b == 8) {  // out[i] is filled in
55
282k
            i++;
56
282k
        }
57
282k
    }
58
27
}
oqs_kem_efrodokem_1344_aes_pack
Line
Count
Source
13
24
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
24
    memset(out, 0, outlen);
16
17
24
    size_t i = 0;            // whole bytes already filled in
18
24
    size_t j = 0;            // whole uint16_t already copied
19
24
    uint16_t w = 0;          // the leftover, not yet copied
20
24
    unsigned char bits = 0;  // the number of lsb in w
21
22
345k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
345k
        unsigned char b = 0;  // bits in out[i] already filled in
35
690k
        while (b < 8) {
36
345k
            int nbits = min(8 - b, bits);
37
345k
            uint16_t mask = (1 << nbits) - 1;
38
345k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
345k
            out[i] = out[i] + (t << (8 - b - nbits));
40
345k
            b += nbits;
41
345k
            bits -= nbits;
42
345k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
345k
            if (bits == 0) {
45
172k
                if (j < inlen) {
46
172k
                    w = in[j];
47
172k
                    bits = lsb;
48
172k
                    j++;
49
172k
                } else {
50
24
                    break;  // the input vector is exhausted
51
24
                }
52
172k
            }
53
345k
        }
54
345k
        if (b == 8) {  // out[i] is filled in
55
345k
            i++;
56
345k
        }
57
345k
    }
58
24
}
oqs_kem_efrodokem_1344_shake_pack
Line
Count
Source
13
21
{ // Pack the input uint16 vector into a char output vector, copying lsb bits from each input element. 
14
  // If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
15
21
    memset(out, 0, outlen);
16
17
21
    size_t i = 0;            // whole bytes already filled in
18
21
    size_t j = 0;            // whole uint16_t already copied
19
21
    uint16_t w = 0;          // the leftover, not yet copied
20
21
    unsigned char bits = 0;  // the number of lsb in w
21
22
301k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
23
        /*
24
        in: |        |        |********|********|
25
                              ^
26
                              j
27
        w : |   ****|
28
                ^
29
               bits
30
        out:|**|**|**|**|**|**|**|**|* |
31
                                    ^^
32
                                    ib
33
        */
34
301k
        unsigned char b = 0;  // bits in out[i] already filled in
35
603k
        while (b < 8) {
36
301k
            int nbits = min(8 - b, bits);
37
301k
            uint16_t mask = (1 << nbits) - 1;
38
301k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
39
301k
            out[i] = out[i] + (t << (8 - b - nbits));
40
301k
            b += nbits;
41
301k
            bits -= nbits;
42
301k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
43
44
301k
            if (bits == 0) {
45
150k
                if (j < inlen) {
46
150k
                    w = in[j];
47
150k
                    bits = lsb;
48
150k
                    j++;
49
150k
                } else {
50
21
                    break;  // the input vector is exhausted
51
21
                }
52
150k
            }
53
301k
        }
54
301k
        if (b == 8) {  // out[i] is filled in
55
301k
            i++;
56
301k
        }
57
301k
    }
58
21
}
59
60
61
void frodo_unpack(uint16_t *out, const size_t outlen, const unsigned char *in, const size_t inlen, const unsigned char lsb) 
62
280
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
280
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
280
    size_t i = 0;            // whole uint16_t already filled in
67
280
    size_t j = 0;            // whole bytes already copied
68
280
    unsigned char w = 0;     // the leftover, not yet copied
69
280
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
1.78M
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
1.78M
        unsigned char b = 0;  // bits in out[i] already filled in
84
5.44M
        while (b < lsb) {
85
3.65M
            int nbits = min(lsb - b, bits);
86
3.65M
            uint16_t mask = (1 << nbits) - 1;
87
3.65M
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
3.65M
            out[i] = out[i] + (t << (lsb - b - nbits));
89
3.65M
            b += nbits;
90
3.65M
            bits -= nbits;
91
3.65M
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
3.65M
            if (bits == 0) {
94
3.55M
                if (j < inlen) {
95
3.55M
                    w = in[j];
96
3.55M
                    bits = 8;
97
3.55M
                    j++;
98
3.55M
                } else {
99
280
                    break;  // the input vector is exhausted
100
280
                }
101
3.55M
            }
102
3.65M
        }
103
1.78M
        if (b == lsb) {  // out[i] is filled in
104
1.78M
            i++;
105
1.78M
        }
106
1.78M
    }
107
280
}
oqs_kem_frodokem_640_aes_unpack
Line
Count
Source
62
8
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
8
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
8
    size_t i = 0;            // whole uint16_t already filled in
67
8
    size_t j = 0;            // whole bytes already copied
68
8
    unsigned char w = 0;     // the leftover, not yet copied
69
8
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
30.8k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
30.8k
        unsigned char b = 0;  // bits in out[i] already filled in
84
115k
        while (b < lsb) {
85
84.8k
            int nbits = min(lsb - b, bits);
86
84.8k
            uint16_t mask = (1 << nbits) - 1;
87
84.8k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
84.8k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
84.8k
            b += nbits;
90
84.8k
            bits -= nbits;
91
84.8k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
84.8k
            if (bits == 0) {
94
57.8k
                if (j < inlen) {
95
57.8k
                    w = in[j];
96
57.8k
                    bits = 8;
97
57.8k
                    j++;
98
57.8k
                } else {
99
8
                    break;  // the input vector is exhausted
100
8
                }
101
57.8k
            }
102
84.8k
        }
103
30.8k
        if (b == lsb) {  // out[i] is filled in
104
30.8k
            i++;
105
30.8k
        }
106
30.8k
    }
107
8
}
oqs_kem_frodokem_640_shake_unpack
Line
Count
Source
62
8
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
8
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
8
    size_t i = 0;            // whole uint16_t already filled in
67
8
    size_t j = 0;            // whole bytes already copied
68
8
    unsigned char w = 0;     // the leftover, not yet copied
69
8
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
30.8k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
30.8k
        unsigned char b = 0;  // bits in out[i] already filled in
84
115k
        while (b < lsb) {
85
84.8k
            int nbits = min(lsb - b, bits);
86
84.8k
            uint16_t mask = (1 << nbits) - 1;
87
84.8k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
84.8k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
84.8k
            b += nbits;
90
84.8k
            bits -= nbits;
91
84.8k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
84.8k
            if (bits == 0) {
94
57.8k
                if (j < inlen) {
95
57.8k
                    w = in[j];
96
57.8k
                    bits = 8;
97
57.8k
                    j++;
98
57.8k
                } else {
99
8
                    break;  // the input vector is exhausted
100
8
                }
101
57.8k
            }
102
84.8k
        }
103
30.8k
        if (b == lsb) {  // out[i] is filled in
104
30.8k
            i++;
105
30.8k
        }
106
30.8k
    }
107
8
}
oqs_kem_frodokem_976_aes_unpack
Line
Count
Source
62
40
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
40
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
40
    size_t i = 0;            // whole uint16_t already filled in
67
40
    size_t j = 0;            // whole bytes already copied
68
40
    unsigned char w = 0;     // the leftover, not yet copied
69
40
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
234k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
234k
        unsigned char b = 0;  // bits in out[i] already filled in
84
704k
        while (b < lsb) {
85
469k
            int nbits = min(lsb - b, bits);
86
469k
            uint16_t mask = (1 << nbits) - 1;
87
469k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
469k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
469k
            b += nbits;
90
469k
            bits -= nbits;
91
469k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
469k
            if (bits == 0) {
94
469k
                if (j < inlen) {
95
469k
                    w = in[j];
96
469k
                    bits = 8;
97
469k
                    j++;
98
469k
                } else {
99
40
                    break;  // the input vector is exhausted
100
40
                }
101
469k
            }
102
469k
        }
103
234k
        if (b == lsb) {  // out[i] is filled in
104
234k
            i++;
105
234k
        }
106
234k
    }
107
40
}
oqs_kem_frodokem_976_shake_unpack
Line
Count
Source
62
44
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
44
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
44
    size_t i = 0;            // whole uint16_t already filled in
67
44
    size_t j = 0;            // whole bytes already copied
68
44
    unsigned char w = 0;     // the leftover, not yet copied
69
44
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
258k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
258k
        unsigned char b = 0;  // bits in out[i] already filled in
84
775k
        while (b < lsb) {
85
516k
            int nbits = min(lsb - b, bits);
86
516k
            uint16_t mask = (1 << nbits) - 1;
87
516k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
516k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
516k
            b += nbits;
90
516k
            bits -= nbits;
91
516k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
516k
            if (bits == 0) {
94
516k
                if (j < inlen) {
95
516k
                    w = in[j];
96
516k
                    bits = 8;
97
516k
                    j++;
98
516k
                } else {
99
44
                    break;  // the input vector is exhausted
100
44
                }
101
516k
            }
102
516k
        }
103
258k
        if (b == lsb) {  // out[i] is filled in
104
258k
            i++;
105
258k
        }
106
258k
    }
107
44
}
oqs_kem_frodokem_1344_aes_unpack
Line
Count
Source
62
20
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
20
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
20
    size_t i = 0;            // whole uint16_t already filled in
67
20
    size_t j = 0;            // whole bytes already copied
68
20
    unsigned char w = 0;     // the leftover, not yet copied
69
20
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
161k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
161k
        unsigned char b = 0;  // bits in out[i] already filled in
84
484k
        while (b < lsb) {
85
323k
            int nbits = min(lsb - b, bits);
86
323k
            uint16_t mask = (1 << nbits) - 1;
87
323k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
323k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
323k
            b += nbits;
90
323k
            bits -= nbits;
91
323k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
323k
            if (bits == 0) {
94
323k
                if (j < inlen) {
95
323k
                    w = in[j];
96
323k
                    bits = 8;
97
323k
                    j++;
98
323k
                } else {
99
20
                    break;  // the input vector is exhausted
100
20
                }
101
323k
            }
102
323k
        }
103
161k
        if (b == lsb) {  // out[i] is filled in
104
161k
            i++;
105
161k
        }
106
161k
    }
107
20
}
oqs_kem_frodokem_1344_shake_unpack
Line
Count
Source
62
12
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
12
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
12
    size_t i = 0;            // whole uint16_t already filled in
67
12
    size_t j = 0;            // whole bytes already copied
68
12
    unsigned char w = 0;     // the leftover, not yet copied
69
12
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
96.9k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
96.9k
        unsigned char b = 0;  // bits in out[i] already filled in
84
290k
        while (b < lsb) {
85
193k
            int nbits = min(lsb - b, bits);
86
193k
            uint16_t mask = (1 << nbits) - 1;
87
193k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
193k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
193k
            b += nbits;
90
193k
            bits -= nbits;
91
193k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
193k
            if (bits == 0) {
94
193k
                if (j < inlen) {
95
193k
                    w = in[j];
96
193k
                    bits = 8;
97
193k
                    j++;
98
193k
                } else {
99
12
                    break;  // the input vector is exhausted
100
12
                }
101
193k
            }
102
193k
        }
103
96.9k
        if (b == lsb) {  // out[i] is filled in
104
96.9k
            i++;
105
96.9k
        }
106
96.9k
    }
107
12
}
oqs_kem_efrodokem_640_aes_unpack
Line
Count
Source
62
12
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
12
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
12
    size_t i = 0;            // whole uint16_t already filled in
67
12
    size_t j = 0;            // whole bytes already copied
68
12
    unsigned char w = 0;     // the leftover, not yet copied
69
12
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
46.2k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
46.2k
        unsigned char b = 0;  // bits in out[i] already filled in
84
173k
        while (b < lsb) {
85
127k
            int nbits = min(lsb - b, bits);
86
127k
            uint16_t mask = (1 << nbits) - 1;
87
127k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
127k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
127k
            b += nbits;
90
127k
            bits -= nbits;
91
127k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
127k
            if (bits == 0) {
94
86.7k
                if (j < inlen) {
95
86.7k
                    w = in[j];
96
86.7k
                    bits = 8;
97
86.7k
                    j++;
98
86.7k
                } else {
99
12
                    break;  // the input vector is exhausted
100
12
                }
101
86.7k
            }
102
127k
        }
103
46.2k
        if (b == lsb) {  // out[i] is filled in
104
46.2k
            i++;
105
46.2k
        }
106
46.2k
    }
107
12
}
oqs_kem_efrodokem_640_shake_unpack
Line
Count
Source
62
4
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
4
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
4
    size_t i = 0;            // whole uint16_t already filled in
67
4
    size_t j = 0;            // whole bytes already copied
68
4
    unsigned char w = 0;     // the leftover, not yet copied
69
4
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
15.4k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
15.4k
        unsigned char b = 0;  // bits in out[i] already filled in
84
57.8k
        while (b < lsb) {
85
42.4k
            int nbits = min(lsb - b, bits);
86
42.4k
            uint16_t mask = (1 << nbits) - 1;
87
42.4k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
42.4k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
42.4k
            b += nbits;
90
42.4k
            bits -= nbits;
91
42.4k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
42.4k
            if (bits == 0) {
94
28.9k
                if (j < inlen) {
95
28.9k
                    w = in[j];
96
28.9k
                    bits = 8;
97
28.9k
                    j++;
98
28.9k
                } else {
99
4
                    break;  // the input vector is exhausted
100
4
                }
101
28.9k
            }
102
42.4k
        }
103
15.4k
        if (b == lsb) {  // out[i] is filled in
104
15.4k
            i++;
105
15.4k
        }
106
15.4k
    }
107
4
}
oqs_kem_efrodokem_976_aes_unpack
Line
Count
Source
62
36
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
36
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
36
    size_t i = 0;            // whole uint16_t already filled in
67
36
    size_t j = 0;            // whole bytes already copied
68
36
    unsigned char w = 0;     // the leftover, not yet copied
69
36
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
211k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
211k
        unsigned char b = 0;  // bits in out[i] already filled in
84
634k
        while (b < lsb) {
85
422k
            int nbits = min(lsb - b, bits);
86
422k
            uint16_t mask = (1 << nbits) - 1;
87
422k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
422k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
422k
            b += nbits;
90
422k
            bits -= nbits;
91
422k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
422k
            if (bits == 0) {
94
422k
                if (j < inlen) {
95
422k
                    w = in[j];
96
422k
                    bits = 8;
97
422k
                    j++;
98
422k
                } else {
99
36
                    break;  // the input vector is exhausted
100
36
                }
101
422k
            }
102
422k
        }
103
211k
        if (b == lsb) {  // out[i] is filled in
104
211k
            i++;
105
211k
        }
106
211k
    }
107
36
}
oqs_kem_efrodokem_976_shake_unpack
Line
Count
Source
62
36
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
36
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
36
    size_t i = 0;            // whole uint16_t already filled in
67
36
    size_t j = 0;            // whole bytes already copied
68
36
    unsigned char w = 0;     // the leftover, not yet copied
69
36
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
211k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
211k
        unsigned char b = 0;  // bits in out[i] already filled in
84
634k
        while (b < lsb) {
85
422k
            int nbits = min(lsb - b, bits);
86
422k
            uint16_t mask = (1 << nbits) - 1;
87
422k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
422k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
422k
            b += nbits;
90
422k
            bits -= nbits;
91
422k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
422k
            if (bits == 0) {
94
422k
                if (j < inlen) {
95
422k
                    w = in[j];
96
422k
                    bits = 8;
97
422k
                    j++;
98
422k
                } else {
99
36
                    break;  // the input vector is exhausted
100
36
                }
101
422k
            }
102
422k
        }
103
211k
        if (b == lsb) {  // out[i] is filled in
104
211k
            i++;
105
211k
        }
106
211k
    }
107
36
}
oqs_kem_efrodokem_1344_aes_unpack
Line
Count
Source
62
32
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
32
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
32
    size_t i = 0;            // whole uint16_t already filled in
67
32
    size_t j = 0;            // whole bytes already copied
68
32
    unsigned char w = 0;     // the leftover, not yet copied
69
32
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
258k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
258k
        unsigned char b = 0;  // bits in out[i] already filled in
84
775k
        while (b < lsb) {
85
517k
            int nbits = min(lsb - b, bits);
86
517k
            uint16_t mask = (1 << nbits) - 1;
87
517k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
517k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
517k
            b += nbits;
90
517k
            bits -= nbits;
91
517k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
517k
            if (bits == 0) {
94
517k
                if (j < inlen) {
95
517k
                    w = in[j];
96
517k
                    bits = 8;
97
517k
                    j++;
98
517k
                } else {
99
32
                    break;  // the input vector is exhausted
100
32
                }
101
517k
            }
102
517k
        }
103
258k
        if (b == lsb) {  // out[i] is filled in
104
258k
            i++;
105
258k
        }
106
258k
    }
107
32
}
oqs_kem_efrodokem_1344_shake_unpack
Line
Count
Source
62
28
{ // Unpack the input char vector into a uint16_t output vector, copying lsb bits
63
  // for each output element from input. outlen must be at least ceil(inlen * 8 / lsb).
64
28
    memset(out, 0, outlen * sizeof(uint16_t));
65
66
28
    size_t i = 0;            // whole uint16_t already filled in
67
28
    size_t j = 0;            // whole bytes already copied
68
28
    unsigned char w = 0;     // the leftover, not yet copied
69
28
    unsigned char bits = 0;  // the number of lsb bits of w
70
71
226k
    while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0)))) {
72
        /*
73
        in: |  |  |  |  |  |  |**|**|...
74
                              ^
75
                              j
76
        w : | *|
77
              ^
78
              bits
79
        out:|   *****|   *****|   ***  |        |...
80
                              ^   ^
81
                              i   b
82
        */
83
226k
        unsigned char b = 0;  // bits in out[i] already filled in
84
678k
        while (b < lsb) {
85
452k
            int nbits = min(lsb - b, bits);
86
452k
            uint16_t mask = (1 << nbits) - 1;
87
452k
            unsigned char t = (w >> (bits - nbits)) & mask;  // the bits to copy from w to out
88
452k
            out[i] = out[i] + (t << (lsb - b - nbits));
89
452k
            b += nbits;
90
452k
            bits -= nbits;
91
452k
            w &= ~(mask << bits);  // not strictly necessary; mostly for debugging
92
93
452k
            if (bits == 0) {
94
452k
                if (j < inlen) {
95
452k
                    w = in[j];
96
452k
                    bits = 8;
97
452k
                    j++;
98
452k
                } else {
99
28
                    break;  // the input vector is exhausted
100
28
                }
101
452k
            }
102
452k
        }
103
226k
        if (b == lsb) {  // out[i] is filled in
104
226k
            i++;
105
226k
        }
106
226k
    }
107
28
}
108
109
110
int8_t ct_verify(const uint16_t *a, const uint16_t *b, size_t len) 
111
140
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
140
    uint16_t r = 0;
114
115
597k
    for (size_t i = 0; i < len; i++) {
116
597k
        r |= a[i] ^ b[i];
117
597k
    }
118
119
140
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
140
    return (int8_t)r;
121
140
}
oqs_kem_frodokem_640_aes_ct_verify
Line
Count
Source
111
4
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
4
    uint16_t r = 0;
114
115
10.3k
    for (size_t i = 0; i < len; i++) {
116
10.3k
        r |= a[i] ^ b[i];
117
10.3k
    }
118
119
4
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
4
    return (int8_t)r;
121
4
}
oqs_kem_frodokem_640_shake_ct_verify
Line
Count
Source
111
4
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
4
    uint16_t r = 0;
114
115
10.3k
    for (size_t i = 0; i < len; i++) {
116
10.3k
        r |= a[i] ^ b[i];
117
10.3k
    }
118
119
4
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
4
    return (int8_t)r;
121
4
}
oqs_kem_frodokem_976_aes_ct_verify
Line
Count
Source
111
20
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
20
    uint16_t r = 0;
114
115
78.7k
    for (size_t i = 0; i < len; i++) {
116
78.7k
        r |= a[i] ^ b[i];
117
78.7k
    }
118
119
20
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
20
    return (int8_t)r;
121
20
}
oqs_kem_frodokem_976_shake_ct_verify
Line
Count
Source
111
22
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
22
    uint16_t r = 0;
114
115
86.6k
    for (size_t i = 0; i < len; i++) {
116
86.5k
        r |= a[i] ^ b[i];
117
86.5k
    }
118
119
22
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
22
    return (int8_t)r;
121
22
}
oqs_kem_frodokem_1344_aes_ct_verify
Line
Count
Source
111
10
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
10
    uint16_t r = 0;
114
115
54.0k
    for (size_t i = 0; i < len; i++) {
116
54.0k
        r |= a[i] ^ b[i];
117
54.0k
    }
118
119
10
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
10
    return (int8_t)r;
121
10
}
oqs_kem_frodokem_1344_shake_ct_verify
Line
Count
Source
111
6
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
6
    uint16_t r = 0;
114
115
32.4k
    for (size_t i = 0; i < len; i++) {
116
32.4k
        r |= a[i] ^ b[i];
117
32.4k
    }
118
119
6
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
6
    return (int8_t)r;
121
6
}
oqs_kem_efrodokem_640_aes_ct_verify
Line
Count
Source
111
6
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
6
    uint16_t r = 0;
114
115
15.5k
    for (size_t i = 0; i < len; i++) {
116
15.5k
        r |= a[i] ^ b[i];
117
15.5k
    }
118
119
6
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
6
    return (int8_t)r;
121
6
}
oqs_kem_efrodokem_640_shake_ct_verify
Line
Count
Source
111
2
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
2
    uint16_t r = 0;
114
115
5.18k
    for (size_t i = 0; i < len; i++) {
116
5.18k
        r |= a[i] ^ b[i];
117
5.18k
    }
118
119
2
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
2
    return (int8_t)r;
121
2
}
oqs_kem_efrodokem_976_aes_ct_verify
Line
Count
Source
111
18
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
18
    uint16_t r = 0;
114
115
70.8k
    for (size_t i = 0; i < len; i++) {
116
70.8k
        r |= a[i] ^ b[i];
117
70.8k
    }
118
119
18
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
18
    return (int8_t)r;
121
18
}
oqs_kem_efrodokem_976_shake_ct_verify
Line
Count
Source
111
18
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
18
    uint16_t r = 0;
114
115
70.8k
    for (size_t i = 0; i < len; i++) {
116
70.8k
        r |= a[i] ^ b[i];
117
70.8k
    }
118
119
18
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
18
    return (int8_t)r;
121
18
}
oqs_kem_efrodokem_1344_aes_ct_verify
Line
Count
Source
111
16
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
16
    uint16_t r = 0;
114
115
86.5k
    for (size_t i = 0; i < len; i++) {
116
86.5k
        r |= a[i] ^ b[i];
117
86.5k
    }
118
119
16
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
16
    return (int8_t)r;
121
16
}
oqs_kem_efrodokem_1344_shake_ct_verify
Line
Count
Source
111
14
{ // Compare two arrays in constant time.
112
  // Returns 0 if the byte arrays are equal, -1 otherwise.
113
14
    uint16_t r = 0;
114
115
75.7k
    for (size_t i = 0; i < len; i++) {
116
75.7k
        r |= a[i] ^ b[i];
117
75.7k
    }
118
119
14
    r = (-(int16_t)(r >> 1) | -(int16_t)(r & 1)) >> (8*sizeof(uint16_t)-1);
120
14
    return (int8_t)r;
121
14
}
122
123
124
void ct_select(uint8_t *r, const uint8_t *a, const uint8_t *b, size_t len, int8_t selector) 
125
70
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
1.87k
    for (size_t i = 0; i < len; i++) {
129
1.80k
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
1.80k
    }
131
70
}
oqs_kem_frodokem_640_aes_ct_select
Line
Count
Source
125
2
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
34
    for (size_t i = 0; i < len; i++) {
129
32
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
32
    }
131
2
}
oqs_kem_frodokem_640_shake_ct_select
Line
Count
Source
125
2
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
34
    for (size_t i = 0; i < len; i++) {
129
32
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
32
    }
131
2
}
oqs_kem_frodokem_976_aes_ct_select
Line
Count
Source
125
10
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
250
    for (size_t i = 0; i < len; i++) {
129
240
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
240
    }
131
10
}
oqs_kem_frodokem_976_shake_ct_select
Line
Count
Source
125
11
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
275
    for (size_t i = 0; i < len; i++) {
129
264
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
264
    }
131
11
}
oqs_kem_frodokem_1344_aes_ct_select
Line
Count
Source
125
5
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
165
    for (size_t i = 0; i < len; i++) {
129
160
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
160
    }
131
5
}
oqs_kem_frodokem_1344_shake_ct_select
Line
Count
Source
125
3
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
99
    for (size_t i = 0; i < len; i++) {
129
96
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
96
    }
131
3
}
oqs_kem_efrodokem_640_aes_ct_select
Line
Count
Source
125
3
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
51
    for (size_t i = 0; i < len; i++) {
129
48
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
48
    }
131
3
}
oqs_kem_efrodokem_640_shake_ct_select
Line
Count
Source
125
1
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
17
    for (size_t i = 0; i < len; i++) {
129
16
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
16
    }
131
1
}
oqs_kem_efrodokem_976_aes_ct_select
Line
Count
Source
125
9
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
225
    for (size_t i = 0; i < len; i++) {
129
216
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
216
    }
131
9
}
oqs_kem_efrodokem_976_shake_ct_select
Line
Count
Source
125
9
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
225
    for (size_t i = 0; i < len; i++) {
129
216
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
216
    }
131
9
}
oqs_kem_efrodokem_1344_aes_ct_select
Line
Count
Source
125
8
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
264
    for (size_t i = 0; i < len; i++) {
129
256
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
256
    }
131
8
}
oqs_kem_efrodokem_1344_shake_ct_select
Line
Count
Source
125
7
{ // Select one of the two input arrays to be moved to r
126
  // If (selector == 0) then load r with a, else if (selector == -1) load r with b
127
128
231
    for (size_t i = 0; i < len; i++) {
129
224
        r[i] = (~selector & a[i]) | (selector & b[i]);
130
224
    }
131
7
}