Skip to content

Commit 3b9a382

Browse files
committed
st.c: seed st hash from random.c
Main Murmur weakness is permutation of a block without seed. Just adding a random seed to each block and finalization we greatly increase security of Murmur.
1 parent ff47c10 commit 3b9a382

File tree

4 files changed

+31
-26
lines changed

4 files changed

+31
-26
lines changed

include/ruby/intern.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ st_index_t rb_hash_start(st_index_t);
763763
st_index_t rb_hash_uint32(st_index_t, uint32_t);
764764
st_index_t rb_hash_uint(st_index_t, st_index_t);
765765
st_index_t rb_hash_end(st_index_t);
766+
#define rb_hash_start(h) st_hash_start((h))
766767
#define rb_hash_uint32(h, i) st_hash_uint32((h), (i))
767768
#define rb_hash_uint(h, i) st_hash_uint((h), (i))
768769
#define rb_hash_end(h) st_hash_end(h)

include/ruby/st.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,8 @@ CONSTFUNC(st_index_t st_hash_uint32(st_index_t h, uint32_t i));
143143
CONSTFUNC(st_index_t st_hash_uint(st_index_t h, st_index_t i));
144144
CONSTFUNC(st_index_t st_hash_end(st_index_t h));
145145
CONSTFUNC(st_index_t st_hash_start(st_index_t h));
146-
#define st_hash_start(h) ((st_index_t)(h))
146+
void st_hash_seed(st_index_t seed[2]); /* init global seed */
147+
147148

148149
RUBY_SYMBOL_EXPORT_END
149150

random.c

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,7 +1473,6 @@ random_s_rand(int argc, VALUE *argv, VALUE obj)
14731473
#endif
14741474
#include "siphash.c"
14751475

1476-
static st_index_t hashseed;
14771476
typedef uint8_t sipseed_keys_t[16];
14781477
static union {
14791478
sipseed_keys_t key;
@@ -1483,19 +1482,16 @@ static union {
14831482
static void
14841483
init_hashseed(struct MT *mt)
14851484
{
1486-
hashseed = genrand_int32(mt);
1487-
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
1488-
hashseed <<= 32;
1489-
hashseed |= genrand_int32(mt);
1490-
#endif
1491-
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
1492-
hashseed <<= 32;
1493-
hashseed |= genrand_int32(mt);
1494-
#endif
1495-
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8
1496-
hashseed <<= 32;
1497-
hashseed |= genrand_int32(mt);
1498-
#endif
1485+
st_index_t hashseed[2];
1486+
int i,b;
1487+
for (i = 0; i < 2; i++) {
1488+
hashseed[i] = genrand_int32(mt);
1489+
for (b = ST_INDEX_BITS - 32; b > 0; b -= 32) {
1490+
hashseed[i] <<= 32;
1491+
hashseed[i] |= genrand_int32(mt);
1492+
}
1493+
}
1494+
st_hash_seed(hashseed);
14991495
}
15001496

15011497
static void
@@ -1507,12 +1503,6 @@ init_siphash(struct MT *mt)
15071503
sipseed.u32[i] = genrand_int32(mt);
15081504
}
15091505

1510-
st_index_t
1511-
rb_hash_start(st_index_t h)
1512-
{
1513-
return st_hash_start(hashseed + h);
1514-
}
1515-
15161506
st_index_t
15171507
rb_memhash(const void *ptr, long len)
15181508
{

st.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,17 @@ st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
12811281
}
12821282
#endif
12831283

1284+
static st_index_t st_seed[2];
1285+
static int st_need_seed = 1;
1286+
void
1287+
st_hash_seed(st_index_t seed[2])
1288+
{
1289+
assert(st_need_seed);
1290+
st_seed[0] = seed[0];
1291+
st_seed[1] = seed[1];
1292+
st_need_seed = 0;
1293+
}
1294+
12841295
#define FNV1_32A_INIT 0x811c9dc5
12851296

12861297
/*
@@ -1320,13 +1331,14 @@ murmur_step(st_index_t h, st_index_t k)
13201331
const st_index_t c1 = BIG_CONSTANT(0x87c37b91,0x114253d5);
13211332
const st_index_t c2 = BIG_CONSTANT(0x4cf5ad43,0x2745937f);
13221333
#endif
1334+
k ^= st_seed[0];
13231335
k *= c1;
13241336
k = ROTL(k, r1);
13251337
k *= c2;
13261338

13271339
h *= c1;
13281340
h = ROTL(h, r2);
1329-
h ^= k;
1341+
h ^= k + st_seed[1];
13301342
return h;
13311343
#undef r1
13321344
#undef r2
@@ -1349,6 +1361,7 @@ murmur_finish(st_index_t h)
13491361
const st_index_t c1 = BIG_CONSTANT(0xbf58476d,0x1ce4e5b9);
13501362
const st_index_t c2 = BIG_CONSTANT(0x94d049bb,0x133111eb);
13511363
#endif
1364+
h ^= st_seed[0];
13521365
h ^= h >> r1;
13531366
h *= c1;
13541367
h ^= h >> r2;
@@ -1360,7 +1373,7 @@ murmur_finish(st_index_t h)
13601373
h *= c2;
13611374
h ^= h >> r3;
13621375
#endif
1363-
return h;
1376+
return h ^ st_seed[1];
13641377
}
13651378

13661379
st_index_t
@@ -1369,6 +1382,7 @@ st_hash(const void *ptr, size_t len, st_index_t h)
13691382
const char *data = ptr;
13701383
st_index_t t = 0;
13711384
size_t l = len;
1385+
assert(!st_need_seed);
13721386

13731387
#define data_at(n) (st_index_t)((unsigned char)data[(n)])
13741388
#define UNALIGNED_ADD_4 UNALIGNED_ADD(2); UNALIGNED_ADD(1); UNALIGNED_ADD(0)
@@ -1509,18 +1523,17 @@ st_hash_end(st_index_t h)
15091523
return h;
15101524
}
15111525

1512-
#undef st_hash_start
15131526
st_index_t
15141527
st_hash_start(st_index_t h)
15151528
{
1516-
return h;
1529+
return h + st_seed[1];
15171530
}
15181531

15191532
static st_index_t
15201533
strhash(st_data_t arg)
15211534
{
15221535
register const char *string = (const char *)arg;
1523-
return st_hash(string, strlen(string), FNV1_32A_INIT);
1536+
return st_hash(string, strlen(string), st_seed[1]);
15241537
}
15251538

15261539
int

0 commit comments

Comments
 (0)