summaryrefslogtreecommitdiff
path: root/umac-l3.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2013-04-11 14:57:24 +0200
committerNiels Möller <nisse@lysator.liu.se>2013-04-11 14:57:24 +0200
commit34aef19b0f571e24b575a92d0262df7fe755bf6b (patch)
tree121ae6bd0c4d973de2891a215f1e9da33c199d71 /umac-l3.c
parentc6f38f5f318f4d1cc816385157cbf09197c54d07 (diff)
downloadnettle-34aef19b0f571e24b575a92d0262df7fe755bf6b.tar.gz
Implemented umac.
Diffstat (limited to 'umac-l3.c')
-rw-r--r--umac-l3.c87
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;
+}