Skip to content

Commit 66de864

Browse files
authored
Merge pull request #505 from urazoff/develop
Add FNV-1a hash function
2 parents 04e9d1e + f37f620 commit 66de864

File tree

12 files changed

+134
-15
lines changed

12 files changed

+134
-15
lines changed

demo/test.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,56 @@ static int test_trivial_stuff(void)
153153
return EXIT_FAILURE;
154154
}
155155

156+
static int test_mp_hash(void)
157+
{
158+
mp_int a;
159+
mp_hval hash;
160+
int i;
161+
int len = 5;
162+
163+
const char *input[] = {
164+
"0",
165+
"///////////////////////////////////////////////////////////////////",
166+
"4n9cbk886QtLQmofprid3l2Q0GD8Yv979Lh8BdZkFE8g2pDUUSMBET/+M/YFyVZ3mBp",
167+
"5NlgzHhmIX05O5YoW5yW5reAlVNtRAlIcN2dfoATnNdc1Cw5lHZUTwNthmK6/ZLKfY6",
168+
"3gweiHDX+ji5utraSe46IJX+uuh7iggs63xIpMP5MriU4Np+LpHI5are8RzS9pKh9xP"
169+
};
170+
const mp_hval hvals[] = {
171+
#if (MP_DIGIT_BIT == 15)
172+
0x50c5d1f,
173+
0x51b3ba04,
174+
0xf83febd7,
175+
0x2dc8624c,
176+
0xf5c2996b
177+
#elif (MP_DIGIT_BIT == 60)
178+
0xaf63bd4c8601b7df,
179+
0xdb090f8a5cd75210,
180+
0xabae35c7872c107d,
181+
0xfec74888bcef5fcd,
182+
0x27ba96030abceda5
183+
#else
184+
0xaf63bd4c8601b7df,
185+
0x7e868fbf541faf44,
186+
0x420cca3a4cb623bb,
187+
0x16636d996304ee7f,
188+
0x33afc9f1b274fa67
189+
#endif
190+
};
191+
192+
DOR(mp_init(&a));
193+
for (i = 0; i < len; ++i) {
194+
DO(mp_read_radix(&a, input[i], 64));
195+
DO(mp_hash(&a, &hash));
196+
EXPECT(hash == hvals[i]);
197+
}
198+
199+
mp_clear(&a);
200+
return EXIT_SUCCESS;
201+
LBL_ERR:
202+
mp_clear(&a);
203+
return EXIT_FAILURE;
204+
}
205+
156206
static int check_get_set_i32(mp_int *a, int32_t b)
157207
{
158208
mp_clear(a);
@@ -2164,6 +2214,7 @@ static int unit_tests(int argc, char **argv)
21642214
#define T3(n, o1, o2, o3) { #n, (MP_HAS(o1) && MP_HAS(o2) && MP_HAS(o3)) ? test_##n : NULL }
21652215
T0(feature_detection),
21662216
T0(trivial_stuff),
2217+
T1(mp_hash, MP_HASH),
21672218
T2(mp_get_set_i32, MP_GET_I32, MP_GET_MAG_U32),
21682219
T2(mp_get_set_i64, MP_GET_I64, MP_GET_MAG_U64),
21692220
T1(mp_and, MP_AND),

doc/bn.tex

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,20 @@ \section{Integer Division and Remainder}
14441444
such that $bc + d = a$. Note that either of $c$ or $d$ can be set to \texttt{NULL} if their value
14451445
is not required. If $b$ is zero the function returns \texttt{MP\_VAL}.
14461446

1447+
\section{Hashing}
1448+
To get a non-cryptographic hash of an \texttt{mp\_int} use the following function.
1449+
1450+
\index{mp\_hash}
1451+
\begin{alltt}
1452+
mp_err mp_hash (mp_int *a, mp_hval *hash);
1453+
\end{alltt}
1454+
1455+
This will create the hash of $a$ following the \mbox{FNV-1a} algorithm as described on
1456+
\url{http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a}. With the
1457+
help of this function one can use an \texttt{mp\_int} as a key in a hash table.
1458+
1459+
NB: The hashing is not stable over different widths of an \texttt{mp\_digit}.
1460+
14471461
\chapter{Multiplication and Squaring}
14481462
\section{Multiplication}
14491463
A full signed integer multiplication can be performed with the following.

libtommath_VS2008.vcproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,10 @@
480480
RelativePath="mp_grow.c"
481481
>
482482
</File>
483+
<File
484+
RelativePath="mp_hash.c"
485+
>
486+
</File>
483487
<File
484488
RelativePath="mp_init.c"
485489
>

makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ mp_cmp.o mp_cmp_d.o mp_cmp_mag.o mp_cnt_lsb.o mp_complement.o mp_copy.o mp_count
3131
mp_div.o mp_div_2.o mp_div_2d.o mp_div_d.o mp_dr_is_modulus.o mp_dr_reduce.o mp_dr_setup.o \
3232
mp_error_to_string.o mp_exch.o mp_expt_n.o mp_exptmod.o mp_exteuclid.o mp_fread.o mp_from_sbin.o \
3333
mp_from_ubin.o mp_fwrite.o mp_gcd.o mp_get_double.o mp_get_i32.o mp_get_i64.o mp_get_l.o mp_get_mag_u32.o \
34-
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o mp_init_l.o \
35-
mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o mp_invmod.o \
36-
mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
34+
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_hash.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o \
35+
mp_init_l.o mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o \
36+
mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
3737
mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \
3838
mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \
3939
mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \

makefile.mingw

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ mp_cmp.o mp_cmp_d.o mp_cmp_mag.o mp_cnt_lsb.o mp_complement.o mp_copy.o mp_count
3333
mp_div.o mp_div_2.o mp_div_2d.o mp_div_d.o mp_dr_is_modulus.o mp_dr_reduce.o mp_dr_setup.o \
3434
mp_error_to_string.o mp_exch.o mp_expt_n.o mp_exptmod.o mp_exteuclid.o mp_fread.o mp_from_sbin.o \
3535
mp_from_ubin.o mp_fwrite.o mp_gcd.o mp_get_double.o mp_get_i32.o mp_get_i64.o mp_get_l.o mp_get_mag_u32.o \
36-
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o mp_init_l.o \
37-
mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o mp_invmod.o \
38-
mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
36+
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_hash.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o \
37+
mp_init_l.o mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o \
38+
mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
3939
mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \
4040
mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \
4141
mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \

makefile.msvc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ mp_cmp.obj mp_cmp_d.obj mp_cmp_mag.obj mp_cnt_lsb.obj mp_complement.obj mp_copy.
2929
mp_div.obj mp_div_2.obj mp_div_2d.obj mp_div_d.obj mp_dr_is_modulus.obj mp_dr_reduce.obj mp_dr_setup.obj \
3030
mp_error_to_string.obj mp_exch.obj mp_expt_n.obj mp_exptmod.obj mp_exteuclid.obj mp_fread.obj mp_from_sbin.obj \
3131
mp_from_ubin.obj mp_fwrite.obj mp_gcd.obj mp_get_double.obj mp_get_i32.obj mp_get_i64.obj mp_get_l.obj mp_get_mag_u32.obj \
32-
mp_get_mag_u64.obj mp_get_mag_ul.obj mp_grow.obj mp_init.obj mp_init_copy.obj mp_init_i32.obj mp_init_i64.obj mp_init_l.obj \
33-
mp_init_multi.obj mp_init_set.obj mp_init_size.obj mp_init_u32.obj mp_init_u64.obj mp_init_ul.obj mp_invmod.obj \
34-
mp_is_square.obj mp_kronecker.obj mp_lcm.obj mp_log_n.obj mp_lshd.obj mp_mod.obj mp_mod_2d.obj \
32+
mp_get_mag_u64.obj mp_get_mag_ul.obj mp_grow.obj mp_hash.obj mp_init.obj mp_init_copy.obj mp_init_i32.obj mp_init_i64.obj \
33+
mp_init_l.obj mp_init_multi.obj mp_init_set.obj mp_init_size.obj mp_init_u32.obj mp_init_u64.obj mp_init_ul.obj \
34+
mp_invmod.obj mp_is_square.obj mp_kronecker.obj mp_lcm.obj mp_log_n.obj mp_lshd.obj mp_mod.obj mp_mod_2d.obj \
3535
mp_montgomery_calc_normalization.obj mp_montgomery_reduce.obj mp_montgomery_setup.obj mp_mul.obj mp_mul_2.obj \
3636
mp_mul_2d.obj mp_mul_d.obj mp_mulmod.obj mp_neg.obj mp_or.obj mp_pack.obj mp_pack_count.obj mp_prime_fermat.obj \
3737
mp_prime_frobenius_underwood.obj mp_prime_is_prime.obj mp_prime_miller_rabin.obj mp_prime_next_prime.obj \

makefile.shared

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ mp_cmp.o mp_cmp_d.o mp_cmp_mag.o mp_cnt_lsb.o mp_complement.o mp_copy.o mp_count
2828
mp_div.o mp_div_2.o mp_div_2d.o mp_div_d.o mp_dr_is_modulus.o mp_dr_reduce.o mp_dr_setup.o \
2929
mp_error_to_string.o mp_exch.o mp_expt_n.o mp_exptmod.o mp_exteuclid.o mp_fread.o mp_from_sbin.o \
3030
mp_from_ubin.o mp_fwrite.o mp_gcd.o mp_get_double.o mp_get_i32.o mp_get_i64.o mp_get_l.o mp_get_mag_u32.o \
31-
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o mp_init_l.o \
32-
mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o mp_invmod.o \
33-
mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
31+
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_hash.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o \
32+
mp_init_l.o mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o \
33+
mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
3434
mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \
3535
mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \
3636
mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \

makefile.unix

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ mp_cmp.o mp_cmp_d.o mp_cmp_mag.o mp_cnt_lsb.o mp_complement.o mp_copy.o mp_count
3434
mp_div.o mp_div_2.o mp_div_2d.o mp_div_d.o mp_dr_is_modulus.o mp_dr_reduce.o mp_dr_setup.o \
3535
mp_error_to_string.o mp_exch.o mp_expt_n.o mp_exptmod.o mp_exteuclid.o mp_fread.o mp_from_sbin.o \
3636
mp_from_ubin.o mp_fwrite.o mp_gcd.o mp_get_double.o mp_get_i32.o mp_get_i64.o mp_get_l.o mp_get_mag_u32.o \
37-
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o mp_init_l.o \
38-
mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o mp_invmod.o \
39-
mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
37+
mp_get_mag_u64.o mp_get_mag_ul.o mp_grow.o mp_hash.o mp_init.o mp_init_copy.o mp_init_i32.o mp_init_i64.o \
38+
mp_init_l.o mp_init_multi.o mp_init_set.o mp_init_size.o mp_init_u32.o mp_init_u64.o mp_init_ul.o \
39+
mp_invmod.o mp_is_square.o mp_kronecker.o mp_lcm.o mp_log_n.o mp_lshd.o mp_mod.o mp_mod_2d.o \
4040
mp_montgomery_calc_normalization.o mp_montgomery_reduce.o mp_montgomery_setup.o mp_mul.o mp_mul_2.o \
4141
mp_mul_2d.o mp_mul_d.o mp_mulmod.o mp_neg.o mp_or.o mp_pack.o mp_pack_count.o mp_prime_fermat.o \
4242
mp_prime_frobenius_underwood.o mp_prime_is_prime.o mp_prime_miller_rabin.o mp_prime_next_prime.o \

mp_hash.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include "tommath_private.h"
2+
#ifdef MP_HASH_C
3+
/* LibTomMath, multiple-precision integer library -- Tom St Denis */
4+
/* SPDX-License-Identifier: Unlicense */
5+
6+
#if defined(MP_16BIT)
7+
#define FNV_1A_INIT ((uint32_t)0x811c9dc5)
8+
#define FNV_1A_PRIME ((uint32_t)0x01000193)
9+
#else
10+
#define FNV_1A_INIT ((uint64_t)0xcbf29ce484222325ULL)
11+
#define FNV_1A_PRIME ((uint64_t)0x100000001b3ULL)
12+
#endif
13+
14+
/* computes hash of mp_int. */
15+
mp_err mp_hash(mp_int *a, mp_hval *hash)
16+
{
17+
int x;
18+
mp_hval hval = FNV_1A_INIT;
19+
mp_digit r, mask, shift;
20+
21+
/* FNV-1a algorithm */
22+
mask = ((mp_digit)1 << 8) - 1uL;
23+
shift = (mp_digit)(MP_DIGIT_BIT - 8);
24+
r = 0;
25+
for (x = a->used; x --> 0;) {
26+
mp_digit rr = a->dp[x] & mask;
27+
hval ^= (mp_hval)(a->dp[x] >> 8) | (r << shift);
28+
hval *= FNV_1A_PRIME;
29+
r = rr;
30+
}
31+
hval ^= mp_isneg(a) ? (mp_hval)1 : (mp_hval)0;
32+
*hash = hval * FNV_1A_PRIME;
33+
34+
return MP_OKAY;
35+
}
36+
#endif

tommath.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ EXPORTS
4747
mp_get_mag_u64
4848
mp_get_mag_ul
4949
mp_grow
50+
mp_hash
5051
mp_init
5152
mp_init_copy
5253
mp_init_i32

tommath.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,15 @@ mp_err mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d) MP_WUR;
488488
/* Y = G**X (mod P) */
489489
mp_err mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y) MP_WUR;
490490

491+
#if defined(MP_16BIT)
492+
typedef uint32_t mp_hval;
493+
#else
494+
typedef uint64_t mp_hval;
495+
#endif
496+
497+
/* computes hash */
498+
mp_err mp_hash(mp_int *a, mp_hval *hash) MP_WUR;
499+
491500
/* ---> Primes <--- */
492501

493502
/* performs one Fermat test of "a" using base "b".

tommath_class.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
# define MP_GET_MAG_U64_C
5454
# define MP_GET_MAG_UL_C
5555
# define MP_GROW_C
56+
# define MP_HASH_C
5657
# define MP_INIT_C
5758
# define MP_INIT_COPY_C
5859
# define MP_INIT_I32_C
@@ -386,6 +387,9 @@
386387
# define S_MP_ZERO_DIGS_C
387388
#endif
388389

390+
#if defined(MP_HASH_C)
391+
#endif
392+
389393
#if defined(MP_INIT_C)
390394
#endif
391395

0 commit comments

Comments
 (0)