Use a power of generator representation of GF(256) multiplication group
to save space time and complexity. * grub-core/disk/raid6_recover.c (raid6_table1): Removed. (raid6_table2): Likewise. (powx): New array. (powx_inv): Likewise. (poly): New const. (grub_raid_block_mul): Replace with ... (grub_raid_block_mulx): ...this. (grub_raid6_init_table): Rewritten. (grub_raid6_recover): Use power of generator representation.
This commit is contained in:
parent
09e2763fb1
commit
11ee4389e2
2 changed files with 42 additions and 54 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2011-11-04 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
Use a power of generator representation of GF(256) multiplication group
|
||||
to save space time and complexity.
|
||||
|
||||
* grub-core/disk/raid6_recover.c (raid6_table1): Removed.
|
||||
(raid6_table2): Likewise.
|
||||
(powx): New array.
|
||||
(powx_inv): Likewise.
|
||||
(poly): New const.
|
||||
(grub_raid_block_mul): Replace with ...
|
||||
(grub_raid_block_mulx): ...this.
|
||||
(grub_raid6_init_table): Rewritten.
|
||||
(grub_raid6_recover): Use power of generator representation.
|
||||
|
||||
2011-11-04 Vladimir Serbinenko <phcoder@gmail.com>
|
||||
|
||||
* grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector
|
||||
|
|
|
@ -26,67 +26,40 @@
|
|||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_uint8_t raid6_table1[256][256];
|
||||
static grub_uint8_t raid6_table2[256][256];
|
||||
/* x**y. */
|
||||
static grub_uint8_t powx[255 * 2];
|
||||
/* Such an s that x**s = y */
|
||||
static int powx_inv[256];
|
||||
static const grub_uint8_t poly = 0x1d;
|
||||
|
||||
static void
|
||||
grub_raid_block_mul (grub_uint8_t mul, char *buf, int size)
|
||||
grub_raid_block_mulx (int mul, char *buf, int size)
|
||||
{
|
||||
int i;
|
||||
grub_uint8_t *p;
|
||||
|
||||
p = (grub_uint8_t *) buf;
|
||||
for (i = 0; i < size; i++, p++)
|
||||
*p = raid6_table1[mul][*p];
|
||||
if (*p)
|
||||
*p = powx[mul + powx_inv[*p]];
|
||||
}
|
||||
|
||||
static void
|
||||
grub_raid6_init_table (void)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
raid6_table1[i][1] = raid6_table1[1][i] = i;
|
||||
|
||||
for (i = 2; i < 256; i++)
|
||||
for (j = i; j < 256; j++)
|
||||
{
|
||||
int n;
|
||||
grub_uint8_t c;
|
||||
|
||||
n = i >> 1;
|
||||
|
||||
c = raid6_table1[n][j];
|
||||
c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0);
|
||||
if (i & 1)
|
||||
c ^= j;
|
||||
|
||||
raid6_table1[j][i] = raid6_table1[i][j] = c;
|
||||
}
|
||||
|
||||
raid6_table2[0][0] = 1;
|
||||
for (i = 1; i < 256; i++)
|
||||
raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2];
|
||||
|
||||
for (i = 0; i < 254; i++)
|
||||
for (j = 0; j < 254; j++)
|
||||
{
|
||||
grub_uint8_t c, n;
|
||||
int k;
|
||||
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
k = i - j;
|
||||
if (k < 0)
|
||||
k += 255;
|
||||
|
||||
c = n = raid6_table2[k][k] ^ 1;
|
||||
for (k = 0; k < 253; k++)
|
||||
c = raid6_table1[c][n];
|
||||
|
||||
raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c];
|
||||
}
|
||||
grub_uint8_t cur = 1;
|
||||
for (i = 0; i < 255; i++)
|
||||
{
|
||||
powx[i] = cur;
|
||||
powx[i + 255] = cur;
|
||||
powx_inv[cur] = i;
|
||||
if (cur & 0x80)
|
||||
cur = (cur << 1) ^ poly;
|
||||
else
|
||||
cur <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
|
@ -126,7 +99,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
|||
0, size, buf)))
|
||||
{
|
||||
grub_raid_block_xor (pbuf, buf, size);
|
||||
grub_raid_block_mul (raid6_table2[i][i], buf, size);
|
||||
grub_raid_block_mulx (i, buf, size);
|
||||
grub_raid_block_xor (qbuf, buf, size);
|
||||
}
|
||||
else
|
||||
|
@ -173,13 +146,13 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
|||
goto quit;
|
||||
|
||||
grub_raid_block_xor (buf, qbuf, size);
|
||||
grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf,
|
||||
grub_raid_block_mulx (255 - bad1, buf,
|
||||
size);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Two bad devices */
|
||||
grub_uint8_t c;
|
||||
int c;
|
||||
|
||||
if ((! array->members[p].device) || (! array->members[q].device))
|
||||
{
|
||||
|
@ -201,11 +174,11 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
|||
|
||||
grub_raid_block_xor (qbuf, buf, size);
|
||||
|
||||
c = raid6_table2[bad2][bad1];
|
||||
grub_raid_block_mul (c, qbuf, size);
|
||||
c = (255 - bad1 + (255 - powx_inv[(powx[bad2 - bad1 + 255] ^ 1)])) % 255;
|
||||
grub_raid_block_mulx (c, qbuf, size);
|
||||
|
||||
c = raid6_table1[raid6_table2[bad2][bad2]][c];
|
||||
grub_raid_block_mul (c, pbuf, size);
|
||||
c = (bad2 + c) % 255;
|
||||
grub_raid_block_mulx (c, pbuf, size);
|
||||
|
||||
grub_raid_block_xor (pbuf, qbuf, size);
|
||||
grub_memcpy (buf, pbuf, size);
|
||||
|
|
Loading…
Reference in a new issue