diff options
Diffstat (limited to 'src/ext')
-rw-r--r-- | src/ext/ed25519/donna/ed25519_tor.c | 9 | ||||
-rw-r--r-- | src/ext/ed25519/ref10/blinding.c | 6 | ||||
-rw-r--r-- | src/ext/keccak-tiny/keccak-tiny-unrolled.c | 72 |
3 files changed, 59 insertions, 28 deletions
diff --git a/src/ext/ed25519/donna/ed25519_tor.c b/src/ext/ed25519/donna/ed25519_tor.c index 52b259dfe1..07f6a0f23a 100644 --- a/src/ext/ed25519/donna/ed25519_tor.c +++ b/src/ext/ed25519/donna/ed25519_tor.c @@ -44,7 +44,8 @@ typedef unsigned char ed25519_signature[64]; typedef unsigned char ed25519_public_key[32]; typedef unsigned char ed25519_secret_key[32]; -static void gettweak(unsigned char *out, const unsigned char *param); +static void ed25519_donna_gettweak(unsigned char *out, + const unsigned char *param); static int ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); @@ -242,7 +243,7 @@ ed25519_donna_sign(unsigned char *sig, const unsigned char *m, size_t mlen, } static void -gettweak(unsigned char *out, const unsigned char *param) +ed25519_donna_gettweak(unsigned char *out, const unsigned char *param) { static const char str[] = "Derive temporary signing key"; ed25519_hash_context ctx; @@ -266,7 +267,7 @@ ed25519_donna_blind_secret_key(unsigned char *out, const unsigned char *inp, ed25519_hash_context ctx; bignum256modm ALIGN(16) sk, t; - gettweak(tweak, param); + ed25519_donna_gettweak(tweak, param); expand256_modm(t, tweak, 32); expand256_modm(sk, inp, 32); @@ -297,7 +298,7 @@ ed25519_donna_blind_public_key(unsigned char *out, const unsigned char *inp, ge25519 ALIGN(16) A, Aprime; bignum256modm ALIGN(16) t; - gettweak(tweak, param); + ed25519_donna_gettweak(tweak, param); expand256_modm(t, tweak, 32); /* No "ge25519_unpack", negate the public key. */ diff --git a/src/ext/ed25519/ref10/blinding.c b/src/ext/ed25519/ref10/blinding.c index 4d9a9cbbe7..ee3e8666fa 100644 --- a/src/ext/ed25519/ref10/blinding.c +++ b/src/ext/ed25519/ref10/blinding.c @@ -10,7 +10,7 @@ #include "crypto.h" static void -gettweak(unsigned char *out, const unsigned char *param) +ed25519_ref10_gettweak(unsigned char *out, const unsigned char *param) { const char str[] = "Derive temporary signing key"; crypto_hash_sha512_2(out, (const unsigned char*)str, strlen(str), param, 32); @@ -26,7 +26,7 @@ int ed25519_ref10_blind_secret_key(unsigned char *out, const char str[] = "Derive temporary signing key hash input"; unsigned char tweak[64]; unsigned char zero[32]; - gettweak(tweak, param); + ed25519_ref10_gettweak(tweak, param); memset(zero, 0, 32); sc_muladd(out, inp, tweak, zero); @@ -50,7 +50,7 @@ int ed25519_ref10_blind_public_key(unsigned char *out, ge_p3 A; ge_p2 Aprime; - gettweak(tweak, param); + ed25519_ref10_gettweak(tweak, param); memset(zero, 0, sizeof(zero)); /* Not the greatest implementation of all of this. I wish I had diff --git a/src/ext/keccak-tiny/keccak-tiny-unrolled.c b/src/ext/keccak-tiny/keccak-tiny-unrolled.c index 4b4f51c7cf..d1342c3601 100644 --- a/src/ext/keccak-tiny/keccak-tiny-unrolled.c +++ b/src/ext/keccak-tiny/keccak-tiny-unrolled.c @@ -11,6 +11,29 @@ #include <string.h> #include "crypto.h" +/******** Endianness conversion helpers ********/ + +static inline uint64_t +loadu64le(const unsigned char *x) { + uint64_t r = 0; + size_t i; + + for (i = 0; i < 8; ++i) { + r |= (uint64_t)x[i] << 8 * i; + } + return r; +} + +static inline void +storeu64le(uint8_t *x, uint64_t u) { + size_t i; + + for(i=0; i<8; ++i) { + x[i] = u; + u >>= 8; + } +} + /******** The Keccak-f[1600] permutation ********/ /*** Constants. ***/ @@ -80,24 +103,26 @@ static inline void keccakf(void* state) { /*** Some helper macros. ***/ -#define _(S) do { S } while (0) -#define FOR(i, ST, L, S) \ - _(for (size_t i = 0; i < L; i += ST) { S; }) -#define mkapply_ds(NAME, S) \ - static inline void NAME(uint8_t* dst, \ - const uint8_t* src, \ - size_t len) { \ - FOR(i, 1, len, S); \ - } -#define mkapply_sd(NAME, S) \ - static inline void NAME(const uint8_t* src, \ - uint8_t* dst, \ - size_t len) { \ - FOR(i, 1, len, S); \ +// `xorin` modified to handle Big Endian systems, `buf` being unaligned on +// systems that care about such things. Assumes that len is a multiple of 8, +// which is always true for the rates we use, and the modified finalize. +static inline void +xorin8(uint8_t *dst, const uint8_t *src, size_t len) { + uint64_t* a = (uint64_t*)dst; // Always aligned. + for (size_t i = 0; i < len; i += 8) { + a[i/8] ^= loadu64le(src + i); } +} -mkapply_ds(xorin, dst[i] ^= src[i]) // xorin -mkapply_sd(setout, dst[i] = src[i]) // setout +// `setout` likewise modified to handle Big Endian systems. Assumes that len +// is a multiple of 8, which is true for every rate we use. +static inline void +setout8(const uint8_t *src, uint8_t *dst, size_t len) { + const uint64_t *si = (const uint64_t*)src; // Always aligned. + for (size_t i = 0; i < len; i+= 8) { + storeu64le(dst+i, si[i/8]); + } +} #define P keccakf #define Plen KECCAK_MAX_RATE @@ -118,7 +143,7 @@ static inline void keccak_absorb_blocks(keccak_state *s, const uint8_t *buf, size_t nr_blocks) { size_t blen = nr_blocks * s->rate; - foldP(buf, blen, xorin); + foldP(buf, blen, xorin8); } static int @@ -161,10 +186,14 @@ static void keccak_finalize(keccak_state *s) { // Xor in the DS and pad frame. - s->a[s->offset] ^= s->delim; - s->a[s->rate - 1] ^= 0x80; + s->block[s->offset++] = s->delim; // DS. + for (size_t i = s->offset; i < s->rate; i++) { + s->block[i] = 0; + } + s->block[s->rate - 1] |= 0x80; // Pad frame. + // Xor in the last block. - xorin(s->a, s->block, s->offset); + xorin8(s->a, s->block, s->rate); memwipe(s->block, 0, sizeof(s->block)); s->finalized = 1; @@ -176,7 +205,7 @@ keccak_squeeze_blocks(keccak_state *s, uint8_t *out, size_t nr_blocks) { for (size_t n = 0; n < nr_blocks; n++) { keccakf(s->a); - setout(s->a, out, s->rate); + setout8(s->a, out, s->rate); out += s->rate; } } @@ -321,6 +350,7 @@ static inline int hash(uint8_t* out, size_t outlen, int ret = 0; keccak_state s; + keccak_cleanse(&s); switch (delim) { case KECCAK_DELIM_DIGEST: |