mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Improve Keccak performance
This commit is contained in:
@@ -254,10 +254,26 @@ void
|
||||
keccak1600_armsha3_xor_bytes(void *state, const unsigned char *data, size_t offset, size_t length)
|
||||
{
|
||||
unsigned char *st = (unsigned char *) state;
|
||||
size_t i;
|
||||
uint64_t t;
|
||||
|
||||
for (i = 0U; i < length; i++) {
|
||||
st[offset + i] ^= data[i];
|
||||
while (length > 0U && (offset & 7U) != 0U) {
|
||||
st[offset] ^= *data;
|
||||
data++;
|
||||
offset++;
|
||||
length--;
|
||||
}
|
||||
while (length >= 8U) {
|
||||
t = LOAD64_LE(st + offset) ^ LOAD64_LE(data);
|
||||
STORE64_LE(st + offset, t);
|
||||
data += 8U;
|
||||
offset += 8U;
|
||||
length -= 8U;
|
||||
}
|
||||
while (length > 0U) {
|
||||
st[offset] ^= *data;
|
||||
data++;
|
||||
offset++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -431,10 +431,26 @@ void
|
||||
keccak1600_ref_xor_bytes(void *state, const unsigned char *data, size_t offset, size_t length)
|
||||
{
|
||||
unsigned char *st = (unsigned char *) state;
|
||||
size_t i;
|
||||
uint64_t t;
|
||||
|
||||
for (i = 0U; i < length; i++) {
|
||||
st[offset + i] ^= data[i];
|
||||
while (length > 0U && (offset & 7U) != 0U) {
|
||||
st[offset] ^= *data;
|
||||
data++;
|
||||
offset++;
|
||||
length--;
|
||||
}
|
||||
while (length >= 8U) {
|
||||
t = LOAD64_LE(st + offset) ^ LOAD64_LE(data);
|
||||
STORE64_LE(st + offset, t);
|
||||
data += 8U;
|
||||
offset += 8U;
|
||||
length -= 8U;
|
||||
}
|
||||
while (length > 0U) {
|
||||
st[offset] ^= *data;
|
||||
data++;
|
||||
offset++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,18 +46,36 @@ sha3_update(sha3_state_internal *state, const unsigned char *in, size_t inlen)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
while (consumed < inlen) {
|
||||
if (state->offset == state->rate) {
|
||||
if (state->offset == state->rate && inlen > 0U) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && inlen > 0U) {
|
||||
chunk_size = state->rate - state->offset;
|
||||
if (chunk_size > inlen) {
|
||||
chunk_size = inlen;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, in, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed = chunk_size;
|
||||
if (state->offset == state->rate && consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = state->rate - state->offset;
|
||||
if (chunk_size > inlen - consumed) {
|
||||
chunk_size = inlen - consumed;
|
||||
}
|
||||
while (inlen - consumed >= state->rate) {
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, state->rate);
|
||||
consumed += state->rate;
|
||||
state->offset = state->rate;
|
||||
if (consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed += chunk_size;
|
||||
}
|
||||
if (consumed < inlen) {
|
||||
chunk_size = inlen - consumed;
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -37,18 +37,36 @@ shake128_ref_update(shake128_state_internal *state, const unsigned char *in, siz
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
while (consumed < inlen) {
|
||||
if (state->offset == SHAKE128_RATE) {
|
||||
if (state->offset == SHAKE128_RATE && inlen > 0U) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && inlen > 0U) {
|
||||
chunk_size = SHAKE128_RATE - state->offset;
|
||||
if (chunk_size > inlen) {
|
||||
chunk_size = inlen;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, in, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed = chunk_size;
|
||||
if (state->offset == SHAKE128_RATE && consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = SHAKE128_RATE - state->offset;
|
||||
if (chunk_size > inlen - consumed) {
|
||||
chunk_size = inlen - consumed;
|
||||
}
|
||||
while (inlen - consumed >= SHAKE128_RATE) {
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, SHAKE128_RATE);
|
||||
consumed += SHAKE128_RATE;
|
||||
state->offset = SHAKE128_RATE;
|
||||
if (consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed += chunk_size;
|
||||
}
|
||||
if (consumed < inlen) {
|
||||
chunk_size = inlen - consumed;
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -94,19 +112,36 @@ shake128_ref_squeeze(shake128_state_internal *state, unsigned char *out, size_t
|
||||
shake128_finalize(state);
|
||||
}
|
||||
|
||||
while (extracted < outlen) {
|
||||
if (state->offset == SHAKE128_RATE) {
|
||||
if (state->offset == SHAKE128_RATE && outlen > 0U) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && outlen > 0U) {
|
||||
chunk_size = SHAKE128_RATE - state->offset;
|
||||
if (chunk_size > outlen) {
|
||||
chunk_size = outlen;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, out, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted = chunk_size;
|
||||
if (state->offset == SHAKE128_RATE && extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = SHAKE128_RATE - state->offset;
|
||||
if (chunk_size > outlen - extracted) {
|
||||
chunk_size = outlen - extracted;
|
||||
}
|
||||
while (outlen - extracted >= SHAKE128_RATE) {
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, SHAKE128_RATE);
|
||||
extracted += SHAKE128_RATE;
|
||||
state->offset = SHAKE128_RATE;
|
||||
if (extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset,
|
||||
chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted += chunk_size;
|
||||
}
|
||||
if (extracted < outlen) {
|
||||
chunk_size = outlen - extracted;
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -37,18 +37,36 @@ shake256_ref_update(shake256_state_internal *state, const unsigned char *in, siz
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
while (consumed < inlen) {
|
||||
if (state->offset == SHAKE256_RATE) {
|
||||
if (state->offset == SHAKE256_RATE && inlen > 0U) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && inlen > 0U) {
|
||||
chunk_size = SHAKE256_RATE - state->offset;
|
||||
if (chunk_size > inlen) {
|
||||
chunk_size = inlen;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, in, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed = chunk_size;
|
||||
if (state->offset == SHAKE256_RATE && consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = SHAKE256_RATE - state->offset;
|
||||
if (chunk_size > inlen - consumed) {
|
||||
chunk_size = inlen - consumed;
|
||||
}
|
||||
while (inlen - consumed >= SHAKE256_RATE) {
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, SHAKE256_RATE);
|
||||
consumed += SHAKE256_RATE;
|
||||
state->offset = SHAKE256_RATE;
|
||||
if (consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed += chunk_size;
|
||||
}
|
||||
if (consumed < inlen) {
|
||||
chunk_size = inlen - consumed;
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -94,19 +112,36 @@ shake256_ref_squeeze(shake256_state_internal *state, unsigned char *out, size_t
|
||||
shake256_finalize(state);
|
||||
}
|
||||
|
||||
while (extracted < outlen) {
|
||||
if (state->offset == SHAKE256_RATE) {
|
||||
if (state->offset == SHAKE256_RATE && outlen > 0U) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && outlen > 0U) {
|
||||
chunk_size = SHAKE256_RATE - state->offset;
|
||||
if (chunk_size > outlen) {
|
||||
chunk_size = outlen;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, out, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted = chunk_size;
|
||||
if (state->offset == SHAKE256_RATE && extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = SHAKE256_RATE - state->offset;
|
||||
if (chunk_size > outlen - extracted) {
|
||||
chunk_size = outlen - extracted;
|
||||
}
|
||||
while (outlen - extracted >= SHAKE256_RATE) {
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, SHAKE256_RATE);
|
||||
extracted += SHAKE256_RATE;
|
||||
state->offset = SHAKE256_RATE;
|
||||
if (extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_24(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset,
|
||||
chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted += chunk_size;
|
||||
}
|
||||
if (extracted < outlen) {
|
||||
chunk_size = outlen - extracted;
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -37,18 +37,36 @@ turboshake128_ref_update(turboshake128_state_internal *state, const unsigned cha
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
while (consumed < inlen) {
|
||||
if (state->offset == TURBOSHAKE128_RATE) {
|
||||
if (state->offset == TURBOSHAKE128_RATE && inlen > 0U) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && inlen > 0U) {
|
||||
chunk_size = TURBOSHAKE128_RATE - state->offset;
|
||||
if (chunk_size > inlen) {
|
||||
chunk_size = inlen;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, in, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed = chunk_size;
|
||||
if (state->offset == TURBOSHAKE128_RATE && consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = TURBOSHAKE128_RATE - state->offset;
|
||||
if (chunk_size > inlen - consumed) {
|
||||
chunk_size = inlen - consumed;
|
||||
}
|
||||
while (inlen - consumed >= TURBOSHAKE128_RATE) {
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, TURBOSHAKE128_RATE);
|
||||
consumed += TURBOSHAKE128_RATE;
|
||||
state->offset = TURBOSHAKE128_RATE;
|
||||
if (consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed += chunk_size;
|
||||
}
|
||||
if (consumed < inlen) {
|
||||
chunk_size = inlen - consumed;
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -94,19 +112,36 @@ turboshake128_ref_squeeze(turboshake128_state_internal *state, unsigned char *ou
|
||||
turboshake128_finalize(state);
|
||||
}
|
||||
|
||||
while (extracted < outlen) {
|
||||
if (state->offset == TURBOSHAKE128_RATE) {
|
||||
if (state->offset == TURBOSHAKE128_RATE && outlen > 0U) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && outlen > 0U) {
|
||||
chunk_size = TURBOSHAKE128_RATE - state->offset;
|
||||
if (chunk_size > outlen) {
|
||||
chunk_size = outlen;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, out, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted = chunk_size;
|
||||
if (state->offset == TURBOSHAKE128_RATE && extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = TURBOSHAKE128_RATE - state->offset;
|
||||
if (chunk_size > outlen - extracted) {
|
||||
chunk_size = outlen - extracted;
|
||||
}
|
||||
while (outlen - extracted >= TURBOSHAKE128_RATE) {
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, TURBOSHAKE128_RATE);
|
||||
extracted += TURBOSHAKE128_RATE;
|
||||
state->offset = TURBOSHAKE128_RATE;
|
||||
if (extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset,
|
||||
chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted += chunk_size;
|
||||
}
|
||||
if (extracted < outlen) {
|
||||
chunk_size = outlen - extracted;
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -37,18 +37,36 @@ turboshake256_ref_update(turboshake256_state_internal *state, const unsigned cha
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
while (consumed < inlen) {
|
||||
if (state->offset == TURBOSHAKE256_RATE) {
|
||||
if (state->offset == TURBOSHAKE256_RATE && inlen > 0U) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && inlen > 0U) {
|
||||
chunk_size = TURBOSHAKE256_RATE - state->offset;
|
||||
if (chunk_size > inlen) {
|
||||
chunk_size = inlen;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, in, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed = chunk_size;
|
||||
if (state->offset == TURBOSHAKE256_RATE && consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = TURBOSHAKE256_RATE - state->offset;
|
||||
if (chunk_size > inlen - consumed) {
|
||||
chunk_size = inlen - consumed;
|
||||
}
|
||||
while (inlen - consumed >= TURBOSHAKE256_RATE) {
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, TURBOSHAKE256_RATE);
|
||||
consumed += TURBOSHAKE256_RATE;
|
||||
state->offset = TURBOSHAKE256_RATE;
|
||||
if (consumed < inlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
consumed += chunk_size;
|
||||
}
|
||||
if (consumed < inlen) {
|
||||
chunk_size = inlen - consumed;
|
||||
crypto_core_keccak1600_xor_bytes(&state->state, &in[consumed], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -94,19 +112,36 @@ turboshake256_ref_squeeze(turboshake256_state_internal *state, unsigned char *ou
|
||||
turboshake256_finalize(state);
|
||||
}
|
||||
|
||||
while (extracted < outlen) {
|
||||
if (state->offset == TURBOSHAKE256_RATE) {
|
||||
if (state->offset == TURBOSHAKE256_RATE && outlen > 0U) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
if (state->offset != 0U && outlen > 0U) {
|
||||
chunk_size = TURBOSHAKE256_RATE - state->offset;
|
||||
if (chunk_size > outlen) {
|
||||
chunk_size = outlen;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, out, state->offset, chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted = chunk_size;
|
||||
if (state->offset == TURBOSHAKE256_RATE && extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
chunk_size = TURBOSHAKE256_RATE - state->offset;
|
||||
if (chunk_size > outlen - extracted) {
|
||||
chunk_size = outlen - extracted;
|
||||
}
|
||||
while (outlen - extracted >= TURBOSHAKE256_RATE) {
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, TURBOSHAKE256_RATE);
|
||||
extracted += TURBOSHAKE256_RATE;
|
||||
state->offset = TURBOSHAKE256_RATE;
|
||||
if (extracted < outlen) {
|
||||
crypto_core_keccak1600_permute_12(&state->state);
|
||||
state->offset = 0;
|
||||
}
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], state->offset,
|
||||
chunk_size);
|
||||
state->offset += chunk_size;
|
||||
extracted += chunk_size;
|
||||
}
|
||||
if (extracted < outlen) {
|
||||
chunk_size = outlen - extracted;
|
||||
crypto_core_keccak1600_extract_bytes(&state->state, &out[extracted], 0U, chunk_size);
|
||||
state->offset = chunk_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user