Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/blst/src/sha256.h
Line
Count
Source
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_SHA256_H__
7
#define __BLS12_381_ASM_SHA256_H__
8
9
#include "vect.h"
10
11
#if (defined(__x86_64__) || defined(__x86_64) || defined(_M_X64)) && \
12
     defined(__SHA__) /* -msha */ && !defined(__BLST_PORTABLE__)
13
# define sha256_block_data_order blst_sha256_block_data_order_shaext
14
#elif defined(__aarch64__) && \
15
      defined(__ARM_FEATURE_CRYPTO) && !defined(__BLST_PORTABLE__)
16
# define sha256_block_data_order blst_sha256_block_armv8
17
#else
18
845
# define sha256_block_data_order blst_sha256_block_data_order
19
#endif
20
0
#define sha256_hcopy blst_sha256_hcopy
21
303
#define sha256_bcopy blst_sha256_bcopy
22
719
#define sha256_emit  blst_sha256_emit
23
24
void sha256_block_data_order(unsigned int *h, const void *inp, size_t blocks);
25
void sha256_hcopy(unsigned int dst[8], const unsigned int src[8]);
26
void sha256_bcopy(void *dst, const void *src, size_t len);
27
28
/*
29
 * If SHA256_CTX conflicts with something, just redefine it to alternative
30
 * custom name prior including this header.
31
 */
32
typedef struct {
33
    unsigned int h[8];
34
    unsigned long long N;
35
    unsigned char buf[64];
36
    size_t off;
37
} SHA256_CTX;
38
39
40
static void sha256_init_h(unsigned int h[8])
41
621
{
42
621
    h[0] = 0x6a09e667U;
43
621
    h[1] = 0xbb67ae85U;
44
621
    h[2] = 0x3c6ef372U;
45
621
    h[3] = 0xa54ff53aU;
46
621
    h[4] = 0x510e527fU;
47
621
    h[5] = 0x9b05688cU;
48
621
    h[6] = 0x1f83d9abU;
49
621
    h[7] = 0x5be0cd19U;
50
621
}
51
52
static void sha256_init(SHA256_CTX *ctx)
53
9
{
54
9
    sha256_init_h(ctx->h);
55
9
    ctx->N = 0;
56
9
    vec_zero(ctx->buf, sizeof(ctx->buf));
57
9
    ctx->off = 0;
58
9
}
59
60
static void sha256_update(SHA256_CTX *ctx, const void *_inp, size_t len)
61
312
{
62
312
    size_t n;
63
312
    const unsigned char *inp = _inp;
64
65
312
    ctx->N += len;
66
67
312
    if ((len != 0) & ((n = ctx->off) != 0)) {
68
134
        size_t rem = sizeof(ctx->buf) - n;
69
70
134
        if (rem > len) {
71
70
            sha256_bcopy(ctx->buf + n, inp, len);
72
70
            ctx->off += len;
73
70
            return;
74
70
        } else {
75
64
            sha256_bcopy(ctx->buf + n, inp, rem);
76
64
            inp += rem;
77
64
            len -= rem;
78
64
            sha256_block_data_order(ctx->h, ctx->buf, 1);
79
64
            vec_zero(ctx->buf, sizeof(ctx->buf));
80
64
            ctx->off = 0;
81
64
        }
82
134
    }
83
84
242
    n = len / sizeof(ctx->buf);
85
242
    if (n > 0) {
86
51
        sha256_block_data_order(ctx->h, inp, n);
87
51
        n *= sizeof(ctx->buf);
88
51
        inp += n;
89
51
        len -= n;
90
51
    }
91
92
242
    if (len)
93
169
        sha256_bcopy(ctx->buf, inp, ctx->off = len);
94
242
}
95
96
214
#define __TOBE32(ptr, val) ((ptr)[0] = (unsigned char)((val)>>24), \
97
214
                            (ptr)[1] = (unsigned char)((val)>>16), \
98
214
                            (ptr)[2] = (unsigned char)((val)>>8),  \
99
214
                            (ptr)[3] = (unsigned char)(val))
100
101
#if 1
102
void sha256_emit(unsigned char md[32], const unsigned int h[8]);
103
#else
104
static void sha256_emit(unsigned char md[32], const unsigned int h[8])
105
{
106
    unsigned int h_i;
107
108
    h_i = h[0]; __TOBE32(md + 0, h_i);
109
    h_i = h[1]; __TOBE32(md + 4, h_i);
110
    h_i = h[2]; __TOBE32(md + 8, h_i);
111
    h_i = h[3]; __TOBE32(md + 12, h_i);
112
    h_i = h[4]; __TOBE32(md + 16, h_i);
113
    h_i = h[5]; __TOBE32(md + 20, h_i);
114
    h_i = h[6]; __TOBE32(md + 24, h_i);
115
    h_i = h[7]; __TOBE32(md + 28, h_i);
116
}
117
#endif
118
119
static void sha256_final(unsigned char md[32], SHA256_CTX *ctx)
120
107
{
121
107
    unsigned long long bits = ctx->N * 8;
122
107
    size_t n = ctx->off;
123
107
    unsigned char *tail;
124
125
107
    ctx->buf[n++] = 0x80;
126
127
107
    if (n > (sizeof(ctx->buf) - 8)) {
128
11
        sha256_block_data_order(ctx->h, ctx->buf, 1);
129
11
        vec_zero(ctx->buf, sizeof(ctx->buf));
130
11
    }
131
132
107
    tail = ctx->buf + sizeof(ctx->buf) - 8;
133
107
    __TOBE32(tail, (unsigned int)(bits >> 32));
134
107
    __TOBE32(tail + 4, (unsigned int)bits);
135
107
    sha256_block_data_order(ctx->h, ctx->buf, 1);
136
107
    sha256_emit(md, ctx->h);
137
107
}
138
139
#undef __TOBE32
140
#endif