faster filterng implementation

This commit is contained in:
cathugger 2017-09-27 21:07:33 +03:00
parent 966cf38205
commit 188f821778
3 changed files with 101 additions and 24 deletions

View file

@ -1,7 +1,7 @@
CC= @CC@
CSTD= -std=c99 -Wall -D_POSIX_C_SOURCE=200112L -no-pie
CFLAGS= $(CSTD) @CFLAGS@ -DED25519_@ED25519IMPL@
CFLAGS= $(CSTD) @CFLAGS@ -DED25519_@ED25519IMPL@ @FILTERDEF@
ASFLAGS= -no-pie
MV= mv
@ -48,7 +48,7 @@ ALLO= $(sort \
ALLC= $(patsubst %.c.o,%.c,$(filter %.c.o %.c,$(ALLO)))
CLEANO= $(filter %.o,$(ALLO))
MAINLIB= -lsodium -lpthread
MAINLIB= -lpthread -lsodium
TEST_ED25519LIB= -lsodium
EXE= mkp224o test_base32 test_base16 test_ed25519

View file

@ -1,8 +1,8 @@
AC_INIT(mkp224o)
# safety check
# sanity check
AC_CONFIG_SRCDIR([main.c])
# C compiler
: ${CFLAGS="-O3 -march=native"}
: ${CFLAGS="-O3 -march=native -fomit-frame-pointer"}
AC_PROG_CC
ed25519impl=""
@ -11,7 +11,7 @@ AC_ARG_ENABLE([ref10],
[use ref10 ed25519 implementation @<:@default=yes@:>@])],
[
AS_IF([test "x$ed25519impl" != "x" -a "$ed25519impl" != "ref10"],
[AC_ERROR([only one ed25519 implementation can be defined"])])
[AC_ERROR([only one ed25519 implementation can be defined])])
ed25519impl="ref10"
],
[]
@ -22,7 +22,7 @@ AC_ARG_ENABLE([amd64_51_30k],
[use amd64_51_30k ed25519 implementation @<:@default=no@:>@])],
[
AS_IF([test "x$ed25519impl" != "x" -a "$ed25519impl" != "amd64_51_30k"],
[AC_ERROR([only one ed25519 implementation can be defined"])])
[AC_ERROR([only one ed25519 implementation can be defined])])
ed25519impl="amd64_51_30k"
],
[]
@ -33,7 +33,7 @@ AC_ARG_ENABLE([amd64_64_24k],
[use amd64_64_24k ed25519 implementation @<:@default=no@:>@])],
[
AS_IF([test "x$ed25519impl" != "x" -a "$ed25519impl" != "amd64_64_24k"],
[AC_ERROR([only one ed25519 implementation can be defined"])])
[AC_ERROR([only one ed25519 implementation can be defined])])
ed25519impl="amd64_64_24k"
],
[]
@ -41,5 +41,18 @@ AC_ARG_ENABLE([amd64_64_24k],
AS_IF([test "x$ed25519impl" == "x"],[ed25519impl=ref10])
AC_ARG_ENABLE([intfilter],
[AS_HELP_STRING([--enable-intfilter],
[use 64bit integers for filtering. faster but limits filter length @<:@default=no@:>@])],
[], [enable_intfilter=no]
)
if test "x$enable_intfilter" = "xyes"
then
FILTERDEF="-DINTFILTER"
else
FILTERDEF=""
fi
AC_SUBST(ED25519IMPL,["$ed25519impl"])
AC_SUBST(FILTERDEF,["$FILTERDEF"])
AC_OUTPUT(Makefile)

98
main.c
View file

@ -66,17 +66,34 @@ struct binfilter {
u8 mask;
} ;
VEC_STRUCT(bfiltervec, struct binfilter) bfilters;
#ifdef INTFILTER
struct intfilter {
u64 f,m;
} ;
VEC_STRUCT(ifiltervec,struct intfilter) ifilters;
#else
VEC_STRUCT(bfiltervec,struct binfilter) bfilters;
#endif
static void filters_init()
{
#ifdef INTFILTER
VEC_INIT(ifilters);
#else
VEC_INIT(bfilters);
#endif
}
static void filters_add(const char *filter)
{
struct binfilter bf;
size_t ret, ret2;
#ifdef INTFILTER
union intconv {
u64 i;
u8 b[8];
} fc,mc;
#endif
if (!base32_valid(filter,&ret)) {
fprintf(stderr, "filter \"%s\" is invalid\n", filter);
@ -85,7 +102,12 @@ static void filters_add(const char *filter)
ret = BASE32_FROM_LEN(ret);
if (!ret)
return;
if (ret > PUBLIC_LEN) {
#ifdef INTFILTER
if (ret > 8)
#else
if (ret > PUBLIC_LEN)
#endif
{
fprintf(stderr, "filter \"%s\" is too long\n", filter);
return;
}
@ -93,19 +115,52 @@ static void filters_add(const char *filter)
assert(ret == ret2);
//printf("--m:%02X\n", bf.mask);
bf.len = ret - 1;
#ifdef INTFILTER
mc.i = 0;
for (size_t i = 0;i < bf.len;++i)
mc.b[i] = 0xFF;
mc.b[bf.len] = bf.mask;
memcpy(fc.b,bf.f,8);
fc.i &= mc.i;
struct intfilter ifltr = {fc.i,mc.i};
VEC_ADD(ifilters,ifltr);
#else
VEC_ADD(bfilters,bf);
#endif
}
static void filters_clean()
{
#ifdef INTFILTER
VEC_FREE(ifilters);
#else
VEC_FREE(bfilters);
#endif
}
static size_t filters_count()
{
#ifdef INTFILTER
return VEC_LENGTH(ifilters);
#else
return VEC_LENGTH(bfilters);
#endif
}
#ifdef INTFILTER
#define FILTERFOR(it) for (it = 0;it < VEC_LENGTH(ifilters);++it)
#define MATCHFILTER(it,pk) ((*(u64 *)(pk) & VEC_BUF(ifilters,it).m) == VEC_BUF(ifilters,it).f)
#else
#define FILTERFOR(it) for (it = 0;it < VEC_LENGTH(bfilters);++it)
#define MATCHFILTER(it,pk) ( \
memcmp(pk,VEC_BUF(bfilters,it).f,VEC_BUF(bfilters,it).len) == 0 && \
(pk[VEC_BUF(bfilters,it).len] & VEC_BUF(bfilters,it).mask) == VEC_BUF(bfilters,it).f[VEC_BUF(bfilters,it).len])
#endif
static void loadfilterfile(const char *fname)
{
char buf[128];
@ -122,7 +177,12 @@ static void loadfilterfile(const char *fname)
static void printfilters()
{
size_t i,l = VEC_LENGTH(bfilters);
size_t i,l;
#ifdef INTFILTER
l = VEC_LENGTH(ifilters);
#else
l = VEC_LENGTH(bfilters);
#endif
if (l)
fprintf(stderr, "filters:\n");
else
@ -131,10 +191,20 @@ static void printfilters()
for (i = 0;i < l;++i) {
char buf0[256],buf1[256];
u8 bufx[128];
#ifdef INTFILTER
size_t len = 0;
u8 *imraw = (u8 *)&VEC_BUF(ifilters,i).m;
while (len < 8 && imraw[len] != 0x00) ++len;
u8 mask = imraw[len-1];
u8 *ifraw = (u8 *)&VEC_BUF(ifilters,i).f;
#else
size_t len = VEC_BUF(bfilters,i).len + 1;
base32_to(buf0,VEC_BUF(bfilters,i).f,len);
memcpy(bufx,VEC_BUF(bfilters,i).f,len);
bufx[len - 1] |= ~VEC_BUF(bfilters,i).mask;
u8 mask = VEC_BUF(bfilters,i).mask;
u8 *ifraw = VEC_BUF(bfilters,i).f;
#endif
base32_to(buf0,ifraw,len);
memcpy(bufx,ifraw,len);
bufx[len - 1] |= ~mask;
base32_to(buf1,bufx,len);
char *a = buf0,*b = buf1;
while (*a && *a == *b)
@ -245,11 +315,8 @@ again:
ed25519_seckey_expand(sk,seed);
ed25519_pubkey(pk,sk);
for (i = 0;i < VEC_LENGTH(bfilters);++i) {
size_t l = VEC_BUF(bfilters,i).len;
if (memcmp(pk,VEC_BUF(bfilters,i).f,l) == 0 &&
(pk[l] & VEC_BUF(bfilters,i).mask) == VEC_BUF(bfilters,i).f[l])
{
FILTERFOR(i) {
if (MATCHFILTER(i,pk)) {
memcpy(&hashsrc[checksumstrlen], &pubonion[pkprefixlen], PUBLIC_LEN);
FIPS202_SHA3_256(hashsrc, sizeof(hashsrc), &pubonion[pkprefixlen + PUBLIC_LEN]);
pubonion[pkprefixlen + PUBLIC_LEN + 2] = 0x03; // version
@ -315,14 +382,11 @@ initseed:
if (endwork)
goto end;
for (i = 0;i < VEC_LENGTH(bfilters);++i) {
size_t l = VEC_BUF(bfilters,i).len;
if (memcmp(pk,VEC_BUF(bfilters,i).f,l) == 0 &&
(pk[l] & VEC_BUF(bfilters,i).mask) == VEC_BUF(bfilters,i).f[l])
{
FILTERFOR(i) {
if (MATCHFILTER(i,pk)) {
// found!
// update secret key with counter
addu64toscalar32(sk, counter);
addu64toscalar32(sk,counter);
// sanity check
if (((sk[0] & 248) == sk[0]) && (((sk[31] & 63) | 64) == sk[31])) {
/* These operations should be a no-op. */