Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

[P1619-2] Fwd: XEX code




Old-ish email from Brian Gladman regarding bit ordering in Galois Field representation.

Begin forwarded message:
From: Brian Gladman <brg@gladman.plus.com>
Date: October 26, 2006 Oct 26, 10:10 AM
To: Matt Ball <matt.ball@quantum.com>
Cc: Doug Whiting <DWhiting@hifn.com>, james hughes <jphughes@mac.com>, Serge Plotkin <plotkin@CS.STANFORD.EDU>
Subject: Re: XEX code

Matt Ball wrote:
Hi All,

Unfortunately, I haven't had much time to look this over.  I've got a
couple comments and some ideas for more test vectors.

- Brian, you might consider using constants from <stdint.h>, such as
'uint32_t', 'uint64_t'.  The current code uses 'uint_32t', which is
almost identical to the stdint.h version within the ANSI C99 standard.

Hi Matt (and Colleagues),

Unfortunately <stdint.h> is a C99 feature that many compilers don't
support. In consequence making any code depend on the existence of
<stdint.h> will pretty well guarantee that it is not portable.

And if I do use the exact names used in <stdint.h>, this can then cause
multiple definition problems when it is available and people try to mix
my code with their own.

All very sad really.

So what I do is to use names that can be converted into the names used
in <stdint.h> by using a simple and foolproof regular expression based
search and replace function (I even offer a regular expression to do
this). So if anyone wants to use my code with the standard names it's
pretty trivial to do this conversion.

This applies to all my published code and is the result of a lot of
problems that arose when I did indeed try to use <stdint.h>.

- A comment on Endian order:  Pretty much all cryptography is specified
in Big-endian order (e.g. AES, SHA).  My recommendation is to keep
big-endian order if possible.  It should be possible to have a
reasonably efficient implementation for either choice.  The AES cipher
already has to do some kind of conversion from bytes to words before
running the rounds.  In looking at the Galois multiply (or rather the
LFSR), I'm thinking it might be useful to do the byte-swap once per
sector, and then handle everything as 32-bit words from that point on
(including the AES operation).  The performance shouldn't be too bad.
(Specifically, see the gf_mulx function in xex.c:  The IS_LITTLE_ENDIAN
case might be simplified if the bytes are first converted to words, and
then handled consistently from that point onward.)

I don't care a great deal about what you define here PROVIDED that, in
the Galois Field representation of the unit field element, the single 1
bit ends up in a position within whatever byte it ends up in that
represents a numeric value of 1.

This amounts to requiring that the mapping that is used maps x^n in the
field to 2^n in the normal integer representation used on almost all
processors.

The GCM mapping in which a unit field element ends up in a byte as 0x80
is an implementation disaster, one that caused me an enormous amount of
pain in building optimised versions of LRW before you folk (thankfully!)
replaced it with XEX.

The four bit sequence to byte array mappings that make possible sense are:

AES byte    0    1  ....   15   16
1.       0x87 0x00  .... 0x00 0x01  - little endian in bytes
2.       0x01 0x00  .... 0x00 0x87  - big endian in bytes
3.       0xe1 0x00  .... 0x00 0x80  - the GCM mapping
4.       0x80 0x00  .... 0x00 0xe1  - reversed GCM mapping

If you want to move from 1 to 2, I don't have too much of a problem in
principle but I have just spent quite a bit of time optimising for 1 :-(

But if you want to move to mapping 3 or 4 (which includes the GCM
mapping) then I will disown you!!

David McGrew and John Viega know my feelings about their terrible
decision to use this mapping, one which I consider to be a disaster for
software implementation.  Why they didn't consult an expert in software
implementation before making this decision is beyond me.

   best regards,

     Brian