-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathsha512_simple.cpp
More file actions
112 lines (94 loc) · 3.07 KB
/
Copy pathsha512_simple.cpp
File metadata and controls
112 lines (94 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
* This file has support for the low level SHA-2 hash routines for L3, L5
*/
#include <string.h>
#include "api.h"
#include "internal.h"
#include "sha512avx.h"
#include "sha512.h"
namespace slh_dsa {
/**
* The L3, L5 version of thash
*/
void key_sha2_L35::thash( unsigned char *out,
const unsigned char *in,
unsigned int inblocks, addr_t addr) {
// thash is never called with inblocks==1, hence we don't need to
// special case that
unsigned char outbuf[sha512_output_size];
// Retrieve precomputed state containing pub_seed
SHA512_CTX ctx;
ctx.init_from_intermediate(state_seeded_512, sha512_block_size);
// Starting at state_seeded, hash the addr structure and the
// input blocks
ctx.update(addr, sha256_addr_bytes);
ctx.update(in, inblocks * len_hash() );
ctx.final(outbuf);
memcpy(out, outbuf, len_hash());
}
/**
* 8-way parallel version of thash; takes 8x as much input and output
* Note that, for inblocks==1, the alternative f_xn function is used
*/
void key_sha2_L35::thash_xn(unsigned char **out,
unsigned char **in,
unsigned int inblocks,
addr_t* addrx8) {
__m256i outbufx8[8][sha512_output_size / sizeof(__m256i)];
sha512ctx4x ctx;
int n = len_hash();
for (int i=0; i<8; i+=4) {
sha512_init_frombytes_x4(&ctx, state_seeded_512, 1024);
sha512_update4x(&ctx,
&addrx8[i+0],
&addrx8[i+1],
&addrx8[i+2],
&addrx8[i+3],
sha256_addr_bytes );
sha512_update4x(&ctx,
in[i+0],
in[i+1],
in[i+2],
in[i+3],
inblocks * n );
sha512_final4x(&ctx,
outbufx8[i+0],
outbufx8[i+1],
outbufx8[i+2],
outbufx8[i+3]);
}
memcpy(out[0], outbufx8[0], n);
memcpy(out[1], outbufx8[1], n);
memcpy(out[2], outbufx8[2], n);
memcpy(out[3], outbufx8[3], n);
memcpy(out[4], outbufx8[4], n);
memcpy(out[5], outbufx8[5], n);
memcpy(out[6], outbufx8[6], n);
memcpy(out[7], outbufx8[7], n);
}
//
// For the single input version of T, fall back to the base version, which
// uses SHA-256
void key_sha2_L35::f_xn(unsigned char **out, unsigned char **in,
addr_t* addrxn) {
key_sha2::thash_xn(out, in, 1, addrxn);
}
// This precomputes the SHA-512 hash state after processing the public seed
void key_sha2_L35::initialize_public_seed(const unsigned char *pub_seed) {
uint8_t block[sha512_block_size];
size_t i;
size_t n = len_hash();
for (i = 0; i < n; ++i) {
block[i] = pub_seed[i];
}
for (; i < sha512_block_size; ++i) {
block[i] = 0;
}
SHA512_CTX ctx;
ctx.init();
ctx.update( block, sha512_block_size );
ctx.export_intermediate( state_seeded_512 );
// Also initialize the SHA-256 initial hash (which we also use)
key_sha2::initialize_public_seed(pub_seed);
}
} /* slh_dsa */