Coverage Report

Created: 2023-12-08 07:00

/src/blst_normal/src/bytes.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright Supranational LLC
3
 * Licensed under the Apache License, Version 2.0, see LICENSE for details.
4
 * SPDX-License-Identifier: Apache-2.0
5
 */
6
#ifndef __BLS12_381_ASM_BYTES_H__
7
#define __BLS12_381_ASM_BYTES_H__
8
9
static inline void bytes_zero(unsigned char *a, size_t num)
10
4.30k
{
11
4.30k
    size_t i;
12
13
619k
    for (i = 0; i < num; i++)
14
615k
        a[i] = 0;
15
4.30k
}
16
17
static inline void limbs_from_be_bytes(limb_t *restrict ret,
18
                                       const unsigned char *in, size_t n)
19
10.5k
{
20
10.5k
    limb_t limb = 0;
21
22
661k
    while(n--) {
23
650k
        limb <<= 8;
24
650k
        limb |= *in++;
25
        /*
26
         * 'if (n % sizeof(limb_t) == 0)' is omitted because it's cheaper
27
         * to perform redundant stores than to pay penalty for
28
         * mispredicted branch. Besides, some compilers unroll the
29
         * loop and remove redundant stores to 'restrict'-ed storage...
30
         */
31
650k
        ret[n / sizeof(limb_t)] = limb;
32
650k
    }
33
10.5k
}
34
35
static inline void be_bytes_from_limbs(unsigned char *out, const limb_t *in,
36
                                       size_t n)
37
563
{
38
563
    limb_t limb;
39
40
27.5k
    while(n--) {
41
27.0k
        limb = in[n / sizeof(limb_t)];
42
27.0k
        *out++ = (unsigned char)(limb >> (8 * (n % sizeof(limb_t))));
43
27.0k
    }
44
563
}
45
46
static inline void limbs_from_le_bytes(limb_t *restrict ret,
47
                                       const unsigned char *in, size_t n)
48
6.25k
{
49
6.25k
    limb_t limb = 0;
50
51
206k
    while(n--) {
52
200k
        limb <<= 8;
53
200k
        limb |= in[n];
54
        /*
55
         * 'if (n % sizeof(limb_t) == 0)' is omitted because it's cheaper
56
         * to perform redundant stores than to pay penalty for
57
         * mispredicted branch. Besides, some compilers unroll the
58
         * loop and remove redundant stores to 'restrict'-ed storage...
59
         */
60
200k
        ret[n / sizeof(limb_t)] = limb;
61
200k
    }
62
6.25k
}
63
64
static inline void le_bytes_from_limbs(unsigned char *out, const limb_t *in,
65
                                       size_t n)
66
6.35k
{
67
6.35k
    const union {
68
6.35k
        long one;
69
6.35k
        char little;
70
6.35k
    } is_endian = { 1 };
71
6.35k
    limb_t limb;
72
6.35k
    size_t i, j, r;
73
74
6.35k
    if ((uptr_t)out == (uptr_t)in && is_endian.little)
75
6.25k
        return;
76
77
98
    r = n % sizeof(limb_t);
78
98
    n /= sizeof(limb_t);
79
80
490
    for(i = 0; i < n; i++) {
81
3.52k
        for (limb = in[i], j = 0; j < sizeof(limb_t); j++, limb >>= 8)
82
3.13k
            *out++ = (unsigned char)limb;
83
392
    }
84
98
    if (r) {
85
0
        for (limb = in[i], j = 0; j < r; j++, limb >>= 8)
86
0
            *out++ = (unsigned char)limb;
87
0
    }
88
98
}
89
90
static inline char hex_from_nibble(unsigned char nibble)
91
0
{
92
0
    int mask = (9 - (nibble &= 0xf)) >> 31;
93
0
    return (char)(nibble + ((('a'-10) & mask) | ('0' & ~mask)));
94
0
}
95
96
static unsigned char nibble_from_hex(char c)
97
0
{
98
0
    int mask, ret;
99
100
0
    mask = (('a'-c-1) & (c-1-'f')) >> 31;
101
0
    ret  = (10 + c - 'a') & mask;
102
0
    mask = (('A'-c-1) & (c-1-'F')) >> 31;
103
0
    ret |= (10 + c - 'A') & mask;
104
0
    mask = (('0'-c-1) & (c-1-'9')) >> 31;
105
0
    ret |= (c - '0') & mask;
106
0
    mask = ((ret-1) & ~mask) >> 31;
107
0
    ret |= 16 & mask;
108
109
0
    return (unsigned char)ret;
110
0
}
111
112
static void bytes_from_hexascii(unsigned char *ret, size_t sz, const char *hex)
113
0
{
114
0
    size_t len;
115
0
    unsigned char b = 0;
116
117
0
    if (hex[0]=='0' && (hex[1]=='x' || hex[1]=='X'))
118
0
        hex += 2;
119
120
0
    for (len = 0; len<2*sz && nibble_from_hex(hex[len])<16; len++) ;
121
122
0
    bytes_zero(ret, sz);
123
124
0
    while(len--) {
125
0
        b <<= 4;
126
0
        b |= nibble_from_hex(*hex++);
127
0
        if (len % 2 == 0)
128
0
            ret[len / 2] = b;
129
0
    }
130
0
}
131
132
static void limbs_from_hexascii(limb_t *ret, size_t sz, const char *hex)
133
0
{
134
0
    size_t len;
135
0
    limb_t limb = 0;
136
137
0
    if (hex[0]=='0' && (hex[1]=='x' || hex[1]=='X'))
138
0
        hex += 2;
139
140
0
    for (len = 0; len<2*sz && nibble_from_hex(hex[len])<16; len++) ;
141
142
0
    vec_zero(ret, sz);
143
144
0
    while(len--) {
145
0
        limb <<= 4;
146
0
        limb |= nibble_from_hex(*hex++);
147
0
        if (len % (2*sizeof(limb_t)) == 0)
148
0
            ret[len / (2*sizeof(limb_t))] = limb;
149
0
    }
150
0
}
151
152
#endif