Currently as per the current standard draft
http://grouper.ieee.org/groups/1619/email/pdf00028.pdf , section 5.2, the logical position index i is calculated as

        i = LA << n.

I'll use the notation of section 5.2 and 4.2.2 throughout the text and in the pseudo-code.

If n is a mutiple of a byte, i.e. n % 8 = 0, the implementation is
straightforward, as we can use ordinary assignment to initialize it. Here's the big-endian C pseudo-code for n = 8, b = 32768 and j = 32768/128 = 256.

const unsigned char j = 256;

void encrypt(... other parameters ..., unsigned long long LA)
{
        unsigned char i[16] = { 0, };
        unsigned char q;

        /*
         * i = LA << 8
         * long long is 64 bits/8 bytes
         */
        *(unsigned long long *)(i + 7) = LA;

        for (q = 0; q < j; q++) {
                /* i + q */
                i[15] = q;
                encrypt_block(... other parameters ..., i);
        }
}

Otherwise, if n % 8 != 0, we have to use useless shifting.

Note that j (data unit size/128) is evidently bounded by 2^32 as no
implementation will use (2^32 * 2^7)-bit units in the foreseeable
future.

Also, LA *should* be bounded 2^64/j (otherwise AES collision probability
will be significant due to the birthday paradox). 2^96 is definitely a
hard limit. Also, no hardware will use 96-bit sector addresses in the foreseeable future.

Thus, to avoid shifting, wouldn't it be reasonable to reserve the lower 4 bytes/32 bits for the block index inside the data unit (q in section 4.2.2) and the upper 12 bytes/96 bits for LA?

In that case, section 5.2 should contain something in the lines of the
following:

-----------

The index i is a 128-bit datatype. It should be viewed as a tuple
        <msb, lsb>,
where msb is the 96-bit most significant half and lsb is the 32-bit least significant half. msb will be used to store the data unit index (LA) and lsb to store the value of the current block index in the data unit. Thus, i will be initialised as

        i.msb = LA

and during the iterated encryption of a data unit lsb will be assigned as follows

        i.lsb = q (from section 4.2.2).

-----------

The pseudo-code for the current hardware where n = 5, b = 4096 and j = 32 is straightforward:

typedef struct {
        unsigned char msb[12];
        unsigned char lsb[4];
} u128;

const unsigned char j = 32;

void encrypt(... other parameters ..., unsigned long long LA)
{
        u128 i = { 0, };
        unsigned char q;

        *(unsigned long long *)i.msb = LA;

        for (q = 0; q < j; q++) {
                i.lsb[3] = q;
                encrypt_block(... other parameters ..., i);
        }
}


Regards,
Mart Sõmermaa

Reply via email to