diff options
author | Niels Möller <nisse@lysator.liu.se> | 2013-04-11 14:57:24 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2013-04-11 14:57:24 +0200 |
commit | 34aef19b0f571e24b575a92d0262df7fe755bf6b (patch) | |
tree | 121ae6bd0c4d973de2891a215f1e9da33c199d71 /umac-l3.c | |
parent | c6f38f5f318f4d1cc816385157cbf09197c54d07 (diff) | |
download | nettle-34aef19b0f571e24b575a92d0262df7fe755bf6b.tar.gz |
Implemented umac.
Diffstat (limited to 'umac-l3.c')
-rw-r--r-- | umac-l3.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/umac-l3.c b/umac-l3.c new file mode 100644 index 00000000..7a13847e --- /dev/null +++ b/umac-l3.c @@ -0,0 +1,87 @@ +/* umac-l3.c + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2013 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "umac.h" + +#include "macros.h" + +/* 2^36 - 5 */ +#define P 0x0000000FFFFFFFFBULL + +#if WORDS_BIGENDIAN +#define BE_SWAP64(x) x +#else +#define BE_SWAP64(x) \ + (((x & 0xff) << 56) \ + | ((x & 0xff00) << 40) \ + | ((x & 0xff0000) << 24) \ + | ((x & 0xff000000) << 8) \ + | ((x >> 8) & 0xff000000) \ + | ((x >> 24) & 0xff0000) \ + | ((x >> 40) & 0xff00) \ + | (x >> 56) ) +#endif + +void +_umac_l3_init (unsigned size, uint64_t *k) +{ + unsigned i; + for (i = 0; i < size; i++) + { + uint64_t w = k[i]; + w = BE_SWAP64 (w); + k[i] = w % P; + } +} + +static uint64_t +umac_l3_word (const uint64_t *k, uint64_t w) +{ + unsigned i; + uint64_t y; + + /* Since it's easiest to process the input word from the low end, + * loop over keys in reverse order. */ + + for (i = y = 0; i < 4; i++, w >>= 16) + y += (w & 0xffff) * k[3-i]; + + return y; +} + +uint32_t +_umac_l3 (const uint64_t *key_1, uint32_t key_2, const uint64_t *m) +{ + uint32_t y = (umac_l3_word (key_1, m[0]) + + umac_l3_word (key_1 + 4, m[1])) % P; + y ^= key_2; +#if !WORDS_BIGENDIAN + y = ((ROTL32(8, y) & 0x00FF00FFUL) + | (ROTL32(24, y) & 0xFF00FF00UL)); +#endif + return y; +} |