Re: [PATCH 2/3] gcm: drop w field from nettle_block16

2019-07-09 Thread Dmitry Eremin-Solenikov
Hello,

вт, 9 июл. 2019 г. в 00:44, Niels Möller :
>
> Dmitry Eremin-Solenikov  writes:
>
> > "unsigned long w" comes from the time when Nettle didn't use uint64_t.
> > It is unused now and thus can be dropped.
>
> I've done something very similar on the block16-refactor branch.

No problem.

> > +  r->u64[0] = (x->u64[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56));
>
> I've found this needs to be (uint64_t) GHASH_POLYNOMIAL << 56. Otherwise
> tests fail when I cross compile for (32-bit) mips and run under qemu.

I've just changed GHASH_POLYNOMIAL to `UINT64_C(0xE1)`. Then
all tests succeed.

> I'm also trying to move helper functions (most or all should be inline)
> to block16-internal.h.
>
> Next, I'm looking into unifying the various shift operations. It seems
> we have the following variants:
>
>Big-endian left shift: cmac, eax, polynomial 0x87
>Little-endian left shift: xts, polynomial 0x87
>Big-endian right shift: gcm, polynomial 0xE1 (bit-reverse of 0x87)

I'm going to need big-endian left shift with polynomial 0x87 for
MGM (Multilinear Galois Mode: draft-smyshlyaev-mgm), so unifying
them will be nice.

-- 
With best wishes
Dmitry
___
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs


Re: [PATCH 2/3] gcm: drop w field from nettle_block16

2019-07-08 Thread Niels Möller
Dmitry Eremin-Solenikov  writes:

> "unsigned long w" comes from the time when Nettle didn't use uint64_t.
> It is unused now and thus can be dropped.

I've done something very similar on the block16-refactor branch.

> +  r->u64[0] = (x->u64[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56));

I've found this needs to be (uint64_t) GHASH_POLYNOMIAL << 56. Otherwise
tests fail when I cross compile for (32-bit) mips and run under qemu.

I'm also trying to move helper functions (most or all should be inline)
to block16-internal.h.

Next, I'm looking into unifying the various shift operations. It seems
we have the following variants:

   Big-endian left shift: cmac, eax, polynomial 0x87
   Little-endian left shift: xts, polynomial 0x87
   Big-endian right shift: gcm, polynomial 0xE1 (bit-reverse of 0x87)

If I understand it correctly after a quick look (long since I looked at
GCM in detail), its represents the polynomials with a peculiar bit-order
where what's otherwise the least significant bit represents the
coefficient of the highest power of x. The multiplication is kind-of
invariant under bit-reversal, but I'm not sure if it's possible to
rearrange it to use a different bit order without explicit bit reversal
of the input. At least, not an easy change.

I'm thinking of some shared macros or inline functions to abstract the
left shift operations, say block16_mulx_be, block16_mulx_le.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.
___
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs


[PATCH 2/3] gcm: drop w field from nettle_block16

2019-07-03 Thread Dmitry Eremin-Solenikov
"unsigned long w" comes from the time when Nettle didn't use uint64_t.
It is unused now and thus can be dropped.

Signed-off-by: Dmitry Eremin-Solenikov 
---
 gcm.c | 126 +-
 1 file changed, 28 insertions(+), 98 deletions(-)

diff --git a/gcm.c b/gcm.c
index 14a6181b032f..e7a0a70bda64 100644
--- a/gcm.c
+++ b/gcm.c
@@ -60,12 +60,8 @@ static void
 gcm_gf_add (union nettle_block16 *r,
const union nettle_block16 *x, const union nettle_block16 *y)
 {
-  r->w[0] = x->w[0] ^ y->w[0];
-  r->w[1] = x->w[1] ^ y->w[1];
-#if SIZEOF_LONG == 4
-  r->w[2] = x->w[2] ^ y->w[2];
-  r->w[3] = x->w[3] ^ y->w[3];
-#endif  
+  r->u64[0] = x->u64[0] ^ y->u64[0];
+  r->u64[1] = x->u64[1] ^ y->u64[1];
 }
 /* Multiplication by 010...0; a big-endian shift right. If the bit
shifted out is one, the defining polynomial is added to cancel it
@@ -77,39 +73,16 @@ gcm_gf_shift (union nettle_block16 *r, const union 
nettle_block16 *x)
 
   /* Shift uses big-endian representation. */
 #if WORDS_BIGENDIAN
-# if SIZEOF_LONG == 4
-  mask = - (x->w[3] & 1);
-  r->w[3] = (x->w[3] >> 1) | ((x->w[2] & 1) << 31);
-  r->w[2] = (x->w[2] >> 1) | ((x->w[1] & 1) << 31);
-  r->w[1] = (x->w[1] >> 1) | ((x->w[0] & 1) << 31);
-  r->w[0] = (x->w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 24)); 
-# elif SIZEOF_LONG == 8
-  mask = - (x->w[1] & 1);
-  r->w[1] = (x->w[1] >> 1) | ((x->w[0] & 1) << 63);
-  r->w[0] = (x->w[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56));
-# else
-#  error Unsupported word size. */
-#endif
+  mask = - (x->u64[1] & 1);
+  r->u64[1] = (x->u64[1] >> 1) | ((x->u64[0] & 1) << 63);
+  r->u64[0] = (x->u64[0] >> 1) ^ (mask & (GHASH_POLYNOMIAL << 56));
 #else /* ! WORDS_BIGENDIAN */
-# if SIZEOF_LONG == 4
 #define RSHIFT_WORD(x) \
-  x) & 0xfefefefeUL) >> 1) \
-   | (((x) & 0x00010101) << 15))
-  mask = - ((x->w[3] >> 24) & 1);
-  r->w[3] = RSHIFT_WORD(x->w[3]) | ((x->w[2] >> 17) & 0x80);
-  r->w[2] = RSHIFT_WORD(x->w[2]) | ((x->w[1] >> 17) & 0x80);
-  r->w[1] = RSHIFT_WORD(x->w[1]) | ((x->w[0] >> 17) & 0x80);
-  r->w[0] = RSHIFT_WORD(x->w[0]) ^ (mask & GHASH_POLYNOMIAL);
-# elif SIZEOF_LONG == 8
-#define RSHIFT_WORD(x) \
-  x) & 0xfefefefefefefefeUL) >> 1) \
-   | (((x) & 0x0001010101010101UL) << 15))
-  mask = - ((x->w[1] >> 56) & 1);
-  r->w[1] = RSHIFT_WORD(x->w[1]) | ((x->w[0] >> 49) & 0x80);
-  r->w[0] = RSHIFT_WORD(x->w[0]) ^ (mask & GHASH_POLYNOMIAL);
-# else
-#  error Unsupported word size. */
-# endif
+  x) & UINT64_C(0xfefefefefefefefe)) >> 1) \
+   | (((x) & UINT64_C(0x0001010101010101)) << 15))
+  mask = - ((x->u64[1] >> 56) & 1);
+  r->u64[1] = RSHIFT_WORD(x->u64[1]) | ((x->u64[0] >> 49) & 0x80);
+  r->u64[0] = RSHIFT_WORD(x->u64[0]) ^ (mask & GHASH_POLYNOMIAL);
 # undef RSHIFT_WORD
 #endif /* ! WORDS_BIGENDIAN */
 }
@@ -160,44 +133,21 @@ shift_table[0x10] = {
 static void
 gcm_gf_shift_4(union nettle_block16 *x)
 {
-  unsigned long *w = x->w;
-  unsigned long reduce;
+  uint64_t *u64 = x->u64;
+  uint64_t reduce;
 
   /* Shift uses big-endian representation. */
 #if WORDS_BIGENDIAN
-# if SIZEOF_LONG == 4
-  reduce = shift_table[w[3] & 0xf];
-  w[3] = (w[3] >> 4) | ((w[2] & 0xf) << 28);
-  w[2] = (w[2] >> 4) | ((w[1] & 0xf) << 28);
-  w[1] = (w[1] >> 4) | ((w[0] & 0xf) << 28);
-  w[0] = (w[0] >> 4) ^ (reduce << 16);
-# elif SIZEOF_LONG == 8
-  reduce = shift_table[w[1] & 0xf];
-  w[1] = (w[1] >> 4) | ((w[0] & 0xf) << 60);
-  w[0] = (w[0] >> 4) ^ (reduce << 48);
-# else
-#  error Unsupported word size. */
-#endif
+  reduce = shift_table[u64[1] & 0xf];
+  u64[1] = (u64[1] >> 4) | ((u64[0] & 0xf) << 60);
+  u64[0] = (u64[0] >> 4) ^ (reduce << 48);
 #else /* ! WORDS_BIGENDIAN */
-# if SIZEOF_LONG == 4
 #define RSHIFT_WORD(x) \
-  x) & 0xf0f0f0f0UL) >> 4) \
-   | (((x) & 0x000f0f0f) << 12))
-  reduce = shift_table[(w[3] >> 24) & 0xf];
-  w[3] = RSHIFT_WORD(w[3]) | ((w[2] >> 20) & 0xf0);
-  w[2] = RSHIFT_WORD(w[2]) | ((w[1] >> 20) & 0xf0);
-  w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 20) & 0xf0);
-  w[0] = RSHIFT_WORD(w[0]) ^ reduce;
-# elif SIZEOF_LONG == 8
-#define RSHIFT_WORD(x) \
-  x) & 0xf0f0f0f0f0f0f0f0UL) >> 4) \
-   | (((x) & 0x000f0f0f0f0f0f0fUL) << 12))
-  reduce = shift_table[(w[1] >> 56) & 0xf];
-  w[1] = RSHIFT_WORD(w[1]) | ((w[0] >> 52) & 0xf0);
-  w[0] = RSHIFT_WORD(w[0]) ^ reduce;
-# else
-#  error Unsupported word size. */
-# endif
+  x) & UINT64_C(0xf0f0f0f0f0f0f0f0)) >> 4) \
+   | (((x) & UINT64_C(0x000f0f0f0f0f0f0f)) << 12))
+  reduce = shift_table[(u64[1] >> 56) & 0xf];
+  u64[1] = RSHIFT_WORD(u64[1]) | ((u64[0] >> 52) & 0xf0);
+  u64[0] = RSHIFT_WORD(u64[0]) ^ reduce;
 # undef RSHIFT_WORD
 #endif /* ! WORDS_BIGENDIAN */
 }
@@ -268,38 +218,18 @@ shift_table[0x100] = {
 static void
 gcm_gf_shift_8(union nettle_block16 *x)
 {
-  unsigned long *w = x->w;
-  unsigned long reduce;
+  uint64_t *u64 = x->u64;
+  uint64_t reduce;
 
   /* Shift uses big-endian representation. */
 #if WORDS_BIGENDIAN
-# if SIZEOF_LONG