mirror of
https://github.com/albertobsd/keyhunt.git
synced 2025-07-28 12:43:35 +02:00
Added basecode, sha256, rmd160, bas58 and bloomfilter
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
*.txt
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
|
11
Makefile
Executable file
11
Makefile
Executable file
@@ -0,0 +1,11 @@
|
||||
default:
|
||||
gcc -O3 -c bloom/bloom.c -o bloom.o -I./bloom/murmur2
|
||||
gcc -O3 -c bloom/murmur2/MurmurHash2.c -o murmurhash2.o
|
||||
gcc -O3 -c sha256/sha256.c -o sha256.o
|
||||
gcc -O3 -c base58/base58.c -o base58.o
|
||||
gcc -O3 -c rmd160/rmd160.c -o rmd160.o
|
||||
gcc -O3 -c keyhunt.c -o keyhunt.o
|
||||
gcc -o keyhunt keyhunt.o base58.o rmd160.o sha256.o bloom.o murmurhash2.o -lgmp -lm -lpthread
|
||||
clean:
|
||||
rm -r *.o
|
||||
|
205
base58/base58.c
Normal file
205
base58/base58.c
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2012-2014 Luke Dashjr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the standard MIT license. See COPYING for more details.
|
||||
*/
|
||||
|
||||
#ifndef WIN32
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libbase58.h"
|
||||
|
||||
bool (*b58_sha256_impl)(void *, const void *, size_t) = NULL;
|
||||
|
||||
static const int8_t b58digits_map[] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8,-1,-1,-1,-1,-1,-1,
|
||||
-1, 9,10,11,12,13,14,15, 16,-1,17,18,19,20,21,-1,
|
||||
22,23,24,25,26,27,28,29, 30,31,32,-1,-1,-1,-1,-1,
|
||||
-1,33,34,35,36,37,38,39, 40,41,42,43,-1,44,45,46,
|
||||
47,48,49,50,51,52,53,54, 55,56,57,-1,-1,-1,-1,-1,
|
||||
};
|
||||
|
||||
typedef uint64_t b58_maxint_t;
|
||||
typedef uint32_t b58_almostmaxint_t;
|
||||
#define b58_almostmaxint_bits (sizeof(b58_almostmaxint_t) * 8)
|
||||
static const b58_almostmaxint_t b58_almostmaxint_mask = ((((b58_maxint_t)1) << b58_almostmaxint_bits) - 1);
|
||||
|
||||
bool b58tobin(void *bin, size_t *binszp, const char *b58, size_t b58sz)
|
||||
{
|
||||
size_t binsz = *binszp;
|
||||
const unsigned char *b58u = (void*)b58;
|
||||
unsigned char *binu = bin;
|
||||
size_t outisz = (binsz + sizeof(b58_almostmaxint_t) - 1) / sizeof(b58_almostmaxint_t);
|
||||
b58_almostmaxint_t outi[outisz];
|
||||
b58_maxint_t t;
|
||||
b58_almostmaxint_t c;
|
||||
size_t i, j;
|
||||
uint8_t bytesleft = binsz % sizeof(b58_almostmaxint_t);
|
||||
b58_almostmaxint_t zeromask = bytesleft ? (b58_almostmaxint_mask << (bytesleft * 8)) : 0;
|
||||
unsigned zerocount = 0;
|
||||
|
||||
if (!b58sz)
|
||||
b58sz = strlen(b58);
|
||||
|
||||
for (i = 0; i < outisz; ++i) {
|
||||
outi[i] = 0;
|
||||
}
|
||||
|
||||
// Leading zeros, just count
|
||||
for (i = 0; i < b58sz && b58u[i] == '1'; ++i)
|
||||
++zerocount;
|
||||
|
||||
for ( ; i < b58sz; ++i)
|
||||
{
|
||||
if (b58u[i] & 0x80)
|
||||
// High-bit set on invalid digit
|
||||
return false;
|
||||
if (b58digits_map[b58u[i]] == -1)
|
||||
// Invalid base58 digit
|
||||
return false;
|
||||
c = (unsigned)b58digits_map[b58u[i]];
|
||||
for (j = outisz; j--; )
|
||||
{
|
||||
t = ((b58_maxint_t)outi[j]) * 58 + c;
|
||||
c = t >> b58_almostmaxint_bits;
|
||||
outi[j] = t & b58_almostmaxint_mask;
|
||||
}
|
||||
if (c)
|
||||
// Output number too big (carry to the next int32)
|
||||
return false;
|
||||
if (outi[0] & zeromask)
|
||||
// Output number too big (last int32 filled too far)
|
||||
return false;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
if (bytesleft) {
|
||||
for (i = bytesleft; i > 0; --i) {
|
||||
*(binu++) = (outi[0] >> (8 * (i - 1))) & 0xff;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
||||
for (; j < outisz; ++j)
|
||||
{
|
||||
for (i = sizeof(*outi); i > 0; --i) {
|
||||
*(binu++) = (outi[j] >> (8 * (i - 1))) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
// Count canonical base58 byte count
|
||||
binu = bin;
|
||||
for (i = 0; i < binsz; ++i)
|
||||
{
|
||||
if (binu[i])
|
||||
break;
|
||||
--*binszp;
|
||||
}
|
||||
*binszp += zerocount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
bool my_dblsha256(void *hash, const void *data, size_t datasz)
|
||||
{
|
||||
uint8_t buf[0x20];
|
||||
return b58_sha256_impl(buf, data, datasz) && b58_sha256_impl(hash, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
int b58check(const void *bin, size_t binsz, const char *base58str, size_t b58sz)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
const uint8_t *binc = bin;
|
||||
unsigned i;
|
||||
if (binsz < 4)
|
||||
return -4;
|
||||
if (!my_dblsha256(buf, bin, binsz - 4))
|
||||
return -2;
|
||||
if (memcmp(&binc[binsz - 4], buf, 4))
|
||||
return -1;
|
||||
|
||||
// Check number of zeros is correct AFTER verifying checksum (to avoid possibility of accessing base58str beyond the end)
|
||||
for (i = 0; binc[i] == '\0' && base58str[i] == '1'; ++i)
|
||||
{} // Just finding the end of zeros, nothing to do in loop
|
||||
if (binc[i] == '\0' || base58str[i] == '1')
|
||||
return -3;
|
||||
|
||||
return binc[0];
|
||||
}
|
||||
|
||||
static const char b58digits_ordered[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
bool b58enc(char *b58, size_t *b58sz, const void *data, size_t binsz)
|
||||
{
|
||||
const uint8_t *bin = data;
|
||||
int carry;
|
||||
size_t i, j, high, zcount = 0;
|
||||
size_t size;
|
||||
|
||||
while (zcount < binsz && !bin[zcount])
|
||||
++zcount;
|
||||
|
||||
size = (binsz - zcount) * 138 / 100 + 1;
|
||||
uint8_t buf[size];
|
||||
memset(buf, 0, size);
|
||||
|
||||
for (i = zcount, high = size - 1; i < binsz; ++i, high = j)
|
||||
{
|
||||
for (carry = bin[i], j = size - 1; (j > high) || carry; --j)
|
||||
{
|
||||
carry += 256 * buf[j];
|
||||
buf[j] = carry % 58;
|
||||
carry /= 58;
|
||||
if (!j) {
|
||||
// Otherwise j wraps to maxint which is > high
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < size && !buf[j]; ++j);
|
||||
|
||||
if (*b58sz <= zcount + size - j)
|
||||
{
|
||||
*b58sz = zcount + size - j + 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (zcount)
|
||||
memset(b58, '1', zcount);
|
||||
for (i = zcount; j < size; ++i, ++j)
|
||||
b58[i] = b58digits_ordered[buf[j]];
|
||||
b58[i] = '\0';
|
||||
*b58sz = i + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz)
|
||||
{
|
||||
uint8_t buf[1 + datasz + 0x20];
|
||||
uint8_t *hash = &buf[1 + datasz];
|
||||
|
||||
buf[0] = ver;
|
||||
memcpy(&buf[1], data, datasz);
|
||||
if (!my_dblsha256(hash, buf, datasz + 1))
|
||||
{
|
||||
*b58c_sz = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return b58enc(b58c, b58c_sz, buf, 1 + datasz + 4);
|
||||
}
|
23
base58/libbase58.h
Normal file
23
base58/libbase58.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef LIBBASE58_H
|
||||
#define LIBBASE58_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern bool (*b58_sha256_impl)(void *, const void *, size_t);
|
||||
|
||||
extern bool b58tobin(void *bin, size_t *binsz, const char *b58, size_t b58sz);
|
||||
extern int b58check(const void *bin, size_t binsz, const char *b58, size_t b58sz);
|
||||
|
||||
extern bool b58enc(char *b58, size_t *b58sz, const void *bin, size_t binsz);
|
||||
extern bool b58check_enc(char *b58c, size_t *b58c_sz, uint8_t ver, const void *data, size_t datasz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
26
bloom/LICENSE
Normal file
26
bloom/LICENSE
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
Copyright (c) 2012,2015,2016,2017 Jyri J. Virkki
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
167
bloom/bloom.c
Normal file
167
bloom/bloom.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2019, Jyri J. Virkki
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is under BSD license. See LICENSE file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Refer to bloom.h for documentation on the public interfaces.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bloom.h"
|
||||
#include "murmurhash2.h"
|
||||
|
||||
#define MAKESTRING(n) STRING(n)
|
||||
#define STRING(n) #n
|
||||
|
||||
|
||||
inline static int test_bit_set_bit(unsigned char * buf,
|
||||
unsigned int x, int set_bit)
|
||||
{
|
||||
unsigned int byte = x >> 3;
|
||||
unsigned char c = buf[byte]; // expensive memory access
|
||||
unsigned int mask = 1 << (x % 8);
|
||||
|
||||
if (c & mask) {
|
||||
return 1;
|
||||
} else {
|
||||
if (set_bit) {
|
||||
buf[byte] = c | mask;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int bloom_check_add(struct bloom * bloom,
|
||||
const void * buffer, int len, int add)
|
||||
{
|
||||
if (bloom->ready == 0) {
|
||||
printf("bloom at %p not initialized!\n", (void *)bloom);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int hits = 0;
|
||||
register unsigned int a = murmurhash2(buffer, len, 0x9747b28c);
|
||||
register unsigned int b = murmurhash2(buffer, len, a);
|
||||
register unsigned int x;
|
||||
register unsigned int i;
|
||||
|
||||
for (i = 0; i < bloom->hashes; i++) {
|
||||
x = (a + i*b) % bloom->bits;
|
||||
if (test_bit_set_bit(bloom->bf, x, add)) {
|
||||
hits++;
|
||||
} else if (!add) {
|
||||
// Don't care about the presence of all the bits. Just our own.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (hits == bloom->hashes) {
|
||||
return 1; // 1 == element already in (or collision)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int bloom_init_size(struct bloom * bloom, int entries, double error,
|
||||
unsigned int cache_size)
|
||||
{
|
||||
return bloom_init(bloom, entries, error);
|
||||
}
|
||||
|
||||
|
||||
int bloom_init(struct bloom * bloom, int entries, double error)
|
||||
{
|
||||
bloom->ready = 0;
|
||||
|
||||
if (entries < 1000 || error == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bloom->entries = entries;
|
||||
bloom->error = error;
|
||||
|
||||
double num = log(bloom->error);
|
||||
double denom = 0.480453013918201; // ln(2)^2
|
||||
bloom->bpe = -(num / denom);
|
||||
|
||||
double dentries = (double)entries;
|
||||
bloom->bits = (int)(dentries * bloom->bpe);
|
||||
|
||||
if (bloom->bits % 8) {
|
||||
bloom->bytes = (bloom->bits / 8) + 1;
|
||||
} else {
|
||||
bloom->bytes = bloom->bits / 8;
|
||||
}
|
||||
|
||||
bloom->hashes = (int)ceil(0.693147180559945 * bloom->bpe); // ln(2)
|
||||
|
||||
bloom->bf = (unsigned char *)calloc(bloom->bytes, sizeof(unsigned char));
|
||||
if (bloom->bf == NULL) { // LCOV_EXCL_START
|
||||
return 1;
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
bloom->ready = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int bloom_check(struct bloom * bloom, const void * buffer, int len)
|
||||
{
|
||||
return bloom_check_add(bloom, buffer, len, 0);
|
||||
}
|
||||
|
||||
|
||||
int bloom_add(struct bloom * bloom, const void * buffer, int len)
|
||||
{
|
||||
return bloom_check_add(bloom, buffer, len, 1);
|
||||
}
|
||||
|
||||
|
||||
void bloom_print(struct bloom * bloom)
|
||||
{
|
||||
printf("bloom at %p\n", (void *)bloom);
|
||||
printf(" ->entries = %d\n", bloom->entries);
|
||||
printf(" ->error = %f\n", bloom->error);
|
||||
printf(" ->bits = %d\n", bloom->bits);
|
||||
printf(" ->bits per elem = %f\n", bloom->bpe);
|
||||
printf(" ->bytes = %d\n", bloom->bytes);
|
||||
printf(" ->hash functions = %d\n", bloom->hashes);
|
||||
}
|
||||
|
||||
|
||||
void bloom_free(struct bloom * bloom)
|
||||
{
|
||||
if (bloom->ready) {
|
||||
free(bloom->bf);
|
||||
}
|
||||
bloom->ready = 0;
|
||||
}
|
||||
|
||||
|
||||
int bloom_reset(struct bloom * bloom)
|
||||
{
|
||||
if (!bloom->ready) return 1;
|
||||
memset(bloom->bf, 0, bloom->bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const char * bloom_version()
|
||||
{
|
||||
return MAKESTRING(BLOOM_VERSION);
|
||||
}
|
173
bloom/bloom.h
Normal file
173
bloom/bloom.h
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2017, Jyri J. Virkki
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is under BSD license. See LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef _BLOOM_H
|
||||
#define _BLOOM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Structure to keep track of one bloom filter. Caller needs to
|
||||
* allocate this and pass it to the functions below. First call for
|
||||
* every struct must be to bloom_init().
|
||||
*
|
||||
*/
|
||||
struct bloom
|
||||
{
|
||||
// These fields are part of the public interface of this structure.
|
||||
// Client code may read these values if desired. Client code MUST NOT
|
||||
// modify any of these.
|
||||
int entries;
|
||||
double error;
|
||||
int bits;
|
||||
int bytes;
|
||||
int hashes;
|
||||
|
||||
// Fields below are private to the implementation. These may go away or
|
||||
// change incompatibly at any moment. Client code MUST NOT access or rely
|
||||
// on these.
|
||||
double bpe;
|
||||
unsigned char * bf;
|
||||
int ready;
|
||||
};
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Initialize the bloom filter for use.
|
||||
*
|
||||
* The filter is initialized with a bit field and number of hash functions
|
||||
* according to the computations from the wikipedia entry:
|
||||
* http://en.wikipedia.org/wiki/Bloom_filter
|
||||
*
|
||||
* Optimal number of bits is:
|
||||
* bits = (entries * ln(error)) / ln(2)^2
|
||||
*
|
||||
* Optimal number of hash functions is:
|
||||
* hashes = bpe * ln(2)
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* entries - The expected number of entries which will be inserted.
|
||||
* Must be at least 1000 (in practice, likely much larger).
|
||||
* error - Probability of collision (as long as entries are not
|
||||
* exceeded).
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* 0 - on success
|
||||
* 1 - on failure
|
||||
*
|
||||
*/
|
||||
int bloom_init(struct bloom * bloom, int entries, double error);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Deprecated, use bloom_init()
|
||||
*
|
||||
*/
|
||||
int bloom_init_size(struct bloom * bloom, int entries, double error,
|
||||
unsigned int cache_size);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Check if the given element is in the bloom filter. Remember this may
|
||||
* return false positive if a collision occurred.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* buffer - Pointer to buffer containing element to check.
|
||||
* len - Size of 'buffer'.
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* 0 - element is not present
|
||||
* 1 - element is present (or false positive due to collision)
|
||||
* -1 - bloom not initialized
|
||||
*
|
||||
*/
|
||||
int bloom_check(struct bloom * bloom, const void * buffer, int len);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Add the given element to the bloom filter.
|
||||
* The return code indicates if the element (or a collision) was already in,
|
||||
* so for the common check+add use case, no need to call check separately.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
* buffer - Pointer to buffer containing element to add.
|
||||
* len - Size of 'buffer'.
|
||||
*
|
||||
* Return:
|
||||
* -------
|
||||
* 0 - element was not present and was added
|
||||
* 1 - element (or a collision) had already been added previously
|
||||
* -1 - bloom not initialized
|
||||
*
|
||||
*/
|
||||
int bloom_add(struct bloom * bloom, const void * buffer, int len);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Print (to stdout) info about this bloom filter. Debugging aid.
|
||||
*
|
||||
*/
|
||||
void bloom_print(struct bloom * bloom);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Deallocate internal storage.
|
||||
*
|
||||
* Upon return, the bloom struct is no longer usable. You may call bloom_init
|
||||
* again on the same struct to reinitialize it again.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
*
|
||||
* Return: none
|
||||
*
|
||||
*/
|
||||
void bloom_free(struct bloom * bloom);
|
||||
|
||||
/** ***************************************************************************
|
||||
* Erase internal storage.
|
||||
*
|
||||
* Erases all elements. Upon return, the bloom struct returns to its initial
|
||||
* (initialized) state.
|
||||
*
|
||||
* Parameters:
|
||||
* -----------
|
||||
* bloom - Pointer to an allocated struct bloom (see above).
|
||||
*
|
||||
* Return:
|
||||
* 0 - on success
|
||||
* 1 - on failure
|
||||
*
|
||||
*/
|
||||
int bloom_reset(struct bloom * bloom);
|
||||
|
||||
|
||||
/** ***************************************************************************
|
||||
* Returns version string compiled into library.
|
||||
*
|
||||
* Return: version string
|
||||
*
|
||||
*/
|
||||
const char * bloom_version();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
64
bloom/murmur2/MurmurHash2.c
Normal file
64
bloom/murmur2/MurmurHash2.c
Normal file
@@ -0,0 +1,64 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// MurmurHash2, by Austin Appleby
|
||||
|
||||
// Note - This code makes a few assumptions about how your machine behaves -
|
||||
|
||||
// 1. We can read a 4-byte value from any address without crashing
|
||||
// 2. sizeof(int) == 4
|
||||
|
||||
// And it has a few limitations -
|
||||
|
||||
// 1. It will not work incrementally.
|
||||
// 2. It will not produce the same results on little-endian and big-endian
|
||||
// machines.
|
||||
|
||||
unsigned int murmurhash2(const void * key, int len, const unsigned int seed)
|
||||
{
|
||||
// 'm' and 'r' are mixing constants generated offline.
|
||||
// They're not really 'magic', they just happen to work well.
|
||||
|
||||
const unsigned int m = 0x5bd1e995;
|
||||
const int r = 24;
|
||||
|
||||
// Initialize the hash to a 'random' value
|
||||
|
||||
unsigned int h = seed ^ len;
|
||||
|
||||
// Mix 4 bytes at a time into the hash
|
||||
|
||||
const unsigned char * data = (const unsigned char *)key;
|
||||
|
||||
while(len >= 4)
|
||||
{
|
||||
unsigned int k = *(unsigned int *)data;
|
||||
|
||||
k *= m;
|
||||
k ^= k >> r;
|
||||
k *= m;
|
||||
|
||||
h *= m;
|
||||
h ^= k;
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
// Handle the last few bytes of the input array
|
||||
|
||||
switch(len)
|
||||
{
|
||||
case 3: h ^= data[2] << 16;
|
||||
case 2: h ^= data[1] << 8;
|
||||
case 1: h ^= data[0];
|
||||
h *= m;
|
||||
};
|
||||
|
||||
// Do a few final mixes of the hash to ensure the last few
|
||||
// bytes are well-incorporated.
|
||||
|
||||
h ^= h >> 13;
|
||||
h *= m;
|
||||
h ^= h >> 15;
|
||||
|
||||
return h;
|
||||
}
|
9
bloom/murmur2/README
Normal file
9
bloom/murmur2/README
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
MurmurHash2.c is taken from
|
||||
|
||||
http://sites.google.com/site/murmurhash/
|
||||
|
||||
According to the above document:
|
||||
|
||||
All code is released to the public domain. For business purposes,
|
||||
Murmurhash is under the MIT license.
|
7
bloom/murmur2/murmurhash2.h
Normal file
7
bloom/murmur2/murmurhash2.h
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
#ifndef _BLOOM_MURMURHASH2
|
||||
#define _BLOOM_MURMURHASH2
|
||||
|
||||
unsigned int murmurhash2(const void * key, int len, const unsigned int seed);
|
||||
|
||||
#endif
|
450
rmd160/rmd160.c
Normal file
450
rmd160/rmd160.c
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* RIPEMD160.c - European RIPE Message Digest, 160 bit (RIPEMD-160)
|
||||
*
|
||||
* The algorithm is by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel.
|
||||
*
|
||||
* The code below is based on the reference implementation by Bosselaers.
|
||||
* It is available at the time of writing from
|
||||
* http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
|
||||
*
|
||||
* Hacked for use in libmd by Martin Hinner <mhi@penguin.cz>
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "rmd160.h"
|
||||
|
||||
/* macro definitions */
|
||||
|
||||
/* ROL(x, n) cyclically rotates x over n bits to the left */
|
||||
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
|
||||
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* the three basic functions F(), G() and H() */
|
||||
#define F(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
|
||||
#define H(x, y, z) (((x) | ~(y)) ^ (z))
|
||||
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
|
||||
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
|
||||
|
||||
/* the eight basic operations FF() through III() */
|
||||
#define FF(a, b, c, d, e, x, s) {\
|
||||
(a) += F((b), (c), (d)) + (x);\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define GG(a, b, c, d, e, x, s) {\
|
||||
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define HH(a, b, c, d, e, x, s) {\
|
||||
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define II(a, b, c, d, e, x, s) {\
|
||||
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define JJ(a, b, c, d, e, x, s) {\
|
||||
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define FFF(a, b, c, d, e, x, s) {\
|
||||
(a) += F((b), (c), (d)) + (x);\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define GGG(a, b, c, d, e, x, s) {\
|
||||
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define HHH(a, b, c, d, e, x, s) {\
|
||||
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define III(a, b, c, d, e, x, s) {\
|
||||
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
#define JJJ(a, b, c, d, e, x, s) {\
|
||||
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
|
||||
(a) = ROL((a), (s)) + (e);\
|
||||
(c) = ROL((c), 10);\
|
||||
}
|
||||
|
||||
/*
|
||||
initializes MDbuffer to "magic constants"
|
||||
*/
|
||||
static void
|
||||
RMDinit (u_int32_t * MDbuf)
|
||||
{
|
||||
MDbuf[0] = 0x67452301UL;
|
||||
MDbuf[1] = 0xefcdab89UL;
|
||||
MDbuf[2] = 0x98badcfeUL;
|
||||
MDbuf[3] = 0x10325476UL;
|
||||
MDbuf[4] = 0xc3d2e1f0UL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
the compression function.
|
||||
transforms MDbuf using message bytes X[0] through X[15]
|
||||
*/
|
||||
static void
|
||||
RMDcompress (u_int32_t * MDbuf, u_int32_t * X)
|
||||
{
|
||||
u_int32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
|
||||
dd = MDbuf[3], ee = MDbuf[4];
|
||||
u_int32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
|
||||
ddd = MDbuf[3], eee = MDbuf[4];
|
||||
|
||||
|
||||
/* round 1 */
|
||||
FF (aa, bb, cc, dd, ee, X[0], 11);
|
||||
FF (ee, aa, bb, cc, dd, X[1], 14);
|
||||
FF (dd, ee, aa, bb, cc, X[2], 15);
|
||||
FF (cc, dd, ee, aa, bb, X[3], 12);
|
||||
FF (bb, cc, dd, ee, aa, X[4], 5);
|
||||
FF (aa, bb, cc, dd, ee, X[5], 8);
|
||||
FF (ee, aa, bb, cc, dd, X[6], 7);
|
||||
FF (dd, ee, aa, bb, cc, X[7], 9);
|
||||
FF (cc, dd, ee, aa, bb, X[8], 11);
|
||||
FF (bb, cc, dd, ee, aa, X[9], 13);
|
||||
FF (aa, bb, cc, dd, ee, X[10], 14);
|
||||
FF (ee, aa, bb, cc, dd, X[11], 15);
|
||||
FF (dd, ee, aa, bb, cc, X[12], 6);
|
||||
FF (cc, dd, ee, aa, bb, X[13], 7);
|
||||
FF (bb, cc, dd, ee, aa, X[14], 9);
|
||||
FF (aa, bb, cc, dd, ee, X[15], 8);
|
||||
|
||||
/* round 2 */
|
||||
GG (ee, aa, bb, cc, dd, X[7], 7);
|
||||
GG (dd, ee, aa, bb, cc, X[4], 6);
|
||||
GG (cc, dd, ee, aa, bb, X[13], 8);
|
||||
GG (bb, cc, dd, ee, aa, X[1], 13);
|
||||
GG (aa, bb, cc, dd, ee, X[10], 11);
|
||||
GG (ee, aa, bb, cc, dd, X[6], 9);
|
||||
GG (dd, ee, aa, bb, cc, X[15], 7);
|
||||
GG (cc, dd, ee, aa, bb, X[3], 15);
|
||||
GG (bb, cc, dd, ee, aa, X[12], 7);
|
||||
GG (aa, bb, cc, dd, ee, X[0], 12);
|
||||
GG (ee, aa, bb, cc, dd, X[9], 15);
|
||||
GG (dd, ee, aa, bb, cc, X[5], 9);
|
||||
GG (cc, dd, ee, aa, bb, X[2], 11);
|
||||
GG (bb, cc, dd, ee, aa, X[14], 7);
|
||||
GG (aa, bb, cc, dd, ee, X[11], 13);
|
||||
GG (ee, aa, bb, cc, dd, X[8], 12);
|
||||
|
||||
/* round 3 */
|
||||
HH (dd, ee, aa, bb, cc, X[3], 11);
|
||||
HH (cc, dd, ee, aa, bb, X[10], 13);
|
||||
HH (bb, cc, dd, ee, aa, X[14], 6);
|
||||
HH (aa, bb, cc, dd, ee, X[4], 7);
|
||||
HH (ee, aa, bb, cc, dd, X[9], 14);
|
||||
HH (dd, ee, aa, bb, cc, X[15], 9);
|
||||
HH (cc, dd, ee, aa, bb, X[8], 13);
|
||||
HH (bb, cc, dd, ee, aa, X[1], 15);
|
||||
HH (aa, bb, cc, dd, ee, X[2], 14);
|
||||
HH (ee, aa, bb, cc, dd, X[7], 8);
|
||||
HH (dd, ee, aa, bb, cc, X[0], 13);
|
||||
HH (cc, dd, ee, aa, bb, X[6], 6);
|
||||
HH (bb, cc, dd, ee, aa, X[13], 5);
|
||||
HH (aa, bb, cc, dd, ee, X[11], 12);
|
||||
HH (ee, aa, bb, cc, dd, X[5], 7);
|
||||
HH (dd, ee, aa, bb, cc, X[12], 5);
|
||||
|
||||
/* round 4 */
|
||||
II (cc, dd, ee, aa, bb, X[1], 11);
|
||||
II (bb, cc, dd, ee, aa, X[9], 12);
|
||||
II (aa, bb, cc, dd, ee, X[11], 14);
|
||||
II (ee, aa, bb, cc, dd, X[10], 15);
|
||||
II (dd, ee, aa, bb, cc, X[0], 14);
|
||||
II (cc, dd, ee, aa, bb, X[8], 15);
|
||||
II (bb, cc, dd, ee, aa, X[12], 9);
|
||||
II (aa, bb, cc, dd, ee, X[4], 8);
|
||||
II (ee, aa, bb, cc, dd, X[13], 9);
|
||||
II (dd, ee, aa, bb, cc, X[3], 14);
|
||||
II (cc, dd, ee, aa, bb, X[7], 5);
|
||||
II (bb, cc, dd, ee, aa, X[15], 6);
|
||||
II (aa, bb, cc, dd, ee, X[14], 8);
|
||||
II (ee, aa, bb, cc, dd, X[5], 6);
|
||||
II (dd, ee, aa, bb, cc, X[6], 5);
|
||||
II (cc, dd, ee, aa, bb, X[2], 12);
|
||||
|
||||
/* round 5 */
|
||||
JJ (bb, cc, dd, ee, aa, X[4], 9);
|
||||
JJ (aa, bb, cc, dd, ee, X[0], 15);
|
||||
JJ (ee, aa, bb, cc, dd, X[5], 5);
|
||||
JJ (dd, ee, aa, bb, cc, X[9], 11);
|
||||
JJ (cc, dd, ee, aa, bb, X[7], 6);
|
||||
JJ (bb, cc, dd, ee, aa, X[12], 8);
|
||||
JJ (aa, bb, cc, dd, ee, X[2], 13);
|
||||
JJ (ee, aa, bb, cc, dd, X[10], 12);
|
||||
JJ (dd, ee, aa, bb, cc, X[14], 5);
|
||||
JJ (cc, dd, ee, aa, bb, X[1], 12);
|
||||
JJ (bb, cc, dd, ee, aa, X[3], 13);
|
||||
JJ (aa, bb, cc, dd, ee, X[8], 14);
|
||||
JJ (ee, aa, bb, cc, dd, X[11], 11);
|
||||
JJ (dd, ee, aa, bb, cc, X[6], 8);
|
||||
JJ (cc, dd, ee, aa, bb, X[15], 5);
|
||||
JJ (bb, cc, dd, ee, aa, X[13], 6);
|
||||
|
||||
/* parallel round 1 */
|
||||
JJJ (aaa, bbb, ccc, ddd, eee, X[5], 8);
|
||||
JJJ (eee, aaa, bbb, ccc, ddd, X[14], 9);
|
||||
JJJ (ddd, eee, aaa, bbb, ccc, X[7], 9);
|
||||
JJJ (ccc, ddd, eee, aaa, bbb, X[0], 11);
|
||||
JJJ (bbb, ccc, ddd, eee, aaa, X[9], 13);
|
||||
JJJ (aaa, bbb, ccc, ddd, eee, X[2], 15);
|
||||
JJJ (eee, aaa, bbb, ccc, ddd, X[11], 15);
|
||||
JJJ (ddd, eee, aaa, bbb, ccc, X[4], 5);
|
||||
JJJ (ccc, ddd, eee, aaa, bbb, X[13], 7);
|
||||
JJJ (bbb, ccc, ddd, eee, aaa, X[6], 7);
|
||||
JJJ (aaa, bbb, ccc, ddd, eee, X[15], 8);
|
||||
JJJ (eee, aaa, bbb, ccc, ddd, X[8], 11);
|
||||
JJJ (ddd, eee, aaa, bbb, ccc, X[1], 14);
|
||||
JJJ (ccc, ddd, eee, aaa, bbb, X[10], 14);
|
||||
JJJ (bbb, ccc, ddd, eee, aaa, X[3], 12);
|
||||
JJJ (aaa, bbb, ccc, ddd, eee, X[12], 6);
|
||||
|
||||
/* parallel round 2 */
|
||||
III (eee, aaa, bbb, ccc, ddd, X[6], 9);
|
||||
III (ddd, eee, aaa, bbb, ccc, X[11], 13);
|
||||
III (ccc, ddd, eee, aaa, bbb, X[3], 15);
|
||||
III (bbb, ccc, ddd, eee, aaa, X[7], 7);
|
||||
III (aaa, bbb, ccc, ddd, eee, X[0], 12);
|
||||
III (eee, aaa, bbb, ccc, ddd, X[13], 8);
|
||||
III (ddd, eee, aaa, bbb, ccc, X[5], 9);
|
||||
III (ccc, ddd, eee, aaa, bbb, X[10], 11);
|
||||
III (bbb, ccc, ddd, eee, aaa, X[14], 7);
|
||||
III (aaa, bbb, ccc, ddd, eee, X[15], 7);
|
||||
III (eee, aaa, bbb, ccc, ddd, X[8], 12);
|
||||
III (ddd, eee, aaa, bbb, ccc, X[12], 7);
|
||||
III (ccc, ddd, eee, aaa, bbb, X[4], 6);
|
||||
III (bbb, ccc, ddd, eee, aaa, X[9], 15);
|
||||
III (aaa, bbb, ccc, ddd, eee, X[1], 13);
|
||||
III (eee, aaa, bbb, ccc, ddd, X[2], 11);
|
||||
|
||||
/* parallel round 3 */
|
||||
HHH (ddd, eee, aaa, bbb, ccc, X[15], 9);
|
||||
HHH (ccc, ddd, eee, aaa, bbb, X[5], 7);
|
||||
HHH (bbb, ccc, ddd, eee, aaa, X[1], 15);
|
||||
HHH (aaa, bbb, ccc, ddd, eee, X[3], 11);
|
||||
HHH (eee, aaa, bbb, ccc, ddd, X[7], 8);
|
||||
HHH (ddd, eee, aaa, bbb, ccc, X[14], 6);
|
||||
HHH (ccc, ddd, eee, aaa, bbb, X[6], 6);
|
||||
HHH (bbb, ccc, ddd, eee, aaa, X[9], 14);
|
||||
HHH (aaa, bbb, ccc, ddd, eee, X[11], 12);
|
||||
HHH (eee, aaa, bbb, ccc, ddd, X[8], 13);
|
||||
HHH (ddd, eee, aaa, bbb, ccc, X[12], 5);
|
||||
HHH (ccc, ddd, eee, aaa, bbb, X[2], 14);
|
||||
HHH (bbb, ccc, ddd, eee, aaa, X[10], 13);
|
||||
HHH (aaa, bbb, ccc, ddd, eee, X[0], 13);
|
||||
HHH (eee, aaa, bbb, ccc, ddd, X[4], 7);
|
||||
HHH (ddd, eee, aaa, bbb, ccc, X[13], 5);
|
||||
|
||||
/* parallel round 4 */
|
||||
GGG (ccc, ddd, eee, aaa, bbb, X[8], 15);
|
||||
GGG (bbb, ccc, ddd, eee, aaa, X[6], 5);
|
||||
GGG (aaa, bbb, ccc, ddd, eee, X[4], 8);
|
||||
GGG (eee, aaa, bbb, ccc, ddd, X[1], 11);
|
||||
GGG (ddd, eee, aaa, bbb, ccc, X[3], 14);
|
||||
GGG (ccc, ddd, eee, aaa, bbb, X[11], 14);
|
||||
GGG (bbb, ccc, ddd, eee, aaa, X[15], 6);
|
||||
GGG (aaa, bbb, ccc, ddd, eee, X[0], 14);
|
||||
GGG (eee, aaa, bbb, ccc, ddd, X[5], 6);
|
||||
GGG (ddd, eee, aaa, bbb, ccc, X[12], 9);
|
||||
GGG (ccc, ddd, eee, aaa, bbb, X[2], 12);
|
||||
GGG (bbb, ccc, ddd, eee, aaa, X[13], 9);
|
||||
GGG (aaa, bbb, ccc, ddd, eee, X[9], 12);
|
||||
GGG (eee, aaa, bbb, ccc, ddd, X[7], 5);
|
||||
GGG (ddd, eee, aaa, bbb, ccc, X[10], 15);
|
||||
GGG (ccc, ddd, eee, aaa, bbb, X[14], 8);
|
||||
|
||||
/* parallel round 5 */
|
||||
FFF (bbb, ccc, ddd, eee, aaa, X[12], 8);
|
||||
FFF (aaa, bbb, ccc, ddd, eee, X[15], 5);
|
||||
FFF (eee, aaa, bbb, ccc, ddd, X[10], 12);
|
||||
FFF (ddd, eee, aaa, bbb, ccc, X[4], 9);
|
||||
FFF (ccc, ddd, eee, aaa, bbb, X[1], 12);
|
||||
FFF (bbb, ccc, ddd, eee, aaa, X[5], 5);
|
||||
FFF (aaa, bbb, ccc, ddd, eee, X[8], 14);
|
||||
FFF (eee, aaa, bbb, ccc, ddd, X[7], 6);
|
||||
FFF (ddd, eee, aaa, bbb, ccc, X[6], 8);
|
||||
FFF (ccc, ddd, eee, aaa, bbb, X[2], 13);
|
||||
FFF (bbb, ccc, ddd, eee, aaa, X[13], 6);
|
||||
FFF (aaa, bbb, ccc, ddd, eee, X[14], 5);
|
||||
FFF (eee, aaa, bbb, ccc, ddd, X[0], 15);
|
||||
FFF (ddd, eee, aaa, bbb, ccc, X[3], 13);
|
||||
FFF (ccc, ddd, eee, aaa, bbb, X[9], 11);
|
||||
FFF (bbb, ccc, ddd, eee, aaa, X[11], 11);
|
||||
|
||||
/* combine results */
|
||||
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
|
||||
MDbuf[1] = MDbuf[2] + dd + eee;
|
||||
MDbuf[2] = MDbuf[3] + ee + aaa;
|
||||
MDbuf[3] = MDbuf[4] + aa + bbb;
|
||||
MDbuf[4] = MDbuf[0] + bb + ccc;
|
||||
MDbuf[0] = ddd;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
puts bytes from strptr into X and pad out; appends length
|
||||
and finally, compresses the last block(s)
|
||||
note: length in bits == 8 * (lswlen + 2^32 mswlen).
|
||||
note: there are (lswlen mod 64) bytes left in strptr.
|
||||
*/
|
||||
static void
|
||||
RMDFinish (u_int32_t * MDbuf, u_int8_t * strptr, u_int32_t lswlen,
|
||||
u_int32_t mswlen)
|
||||
{
|
||||
u_int32_t i; /* counter */
|
||||
u_int32_t X[16]; /* message words */
|
||||
|
||||
memset (X, 0, 16 * sizeof (u_int32_t));
|
||||
|
||||
/* put bytes from strptr into X */
|
||||
for (i = 0; i < (lswlen & 63); i++)
|
||||
{
|
||||
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
|
||||
X[i >> 2] ^= (u_int32_t) * strptr++ << (8 * (i & 3));
|
||||
}
|
||||
|
||||
/* append the bit m_n == 1 */
|
||||
X[(lswlen >> 2) & 15] ^= (u_int32_t) 1 << (8 * (lswlen & 3) + 7);
|
||||
|
||||
if ((lswlen & 63) > 55)
|
||||
{
|
||||
/* length goes to next block */
|
||||
RMDcompress (MDbuf, X);
|
||||
memset (X, 0, 16 * sizeof (u_int32_t));
|
||||
}
|
||||
|
||||
/* append length in bits */
|
||||
X[14] = lswlen << 3;
|
||||
X[15] = (lswlen >> 29) | (mswlen << 3);
|
||||
RMDcompress (MDbuf, X);
|
||||
}
|
||||
|
||||
/*
|
||||
Shuffle the bytes into little-endian order within words, as per the
|
||||
RIPEMD-160 spec (which follows MD4 conventions).
|
||||
*/
|
||||
static void
|
||||
rmd160ByteSwap (u_int32_t * dest, u_int8_t const *src, unsigned int words)
|
||||
{
|
||||
do
|
||||
{
|
||||
*dest++ = (u_int32_t) ((unsigned) src[3] << 8 | src[2]) << 16 |
|
||||
((unsigned) src[1] << 8 | src[0]);
|
||||
src += 4;
|
||||
}
|
||||
while (--words);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize the RIPEMD-160 values
|
||||
*/
|
||||
void
|
||||
RMD160Init (RMD160_CTX * ctx)
|
||||
{
|
||||
/* Set the h-vars to their initial values */
|
||||
RMDinit (ctx->iv);
|
||||
|
||||
/* Initialise bit count */
|
||||
ctx->bytesHi = 0;
|
||||
ctx->bytesLo = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Update the RIPEMD-160 hash state for a block of data.
|
||||
*/
|
||||
void RMD160Update(RMD160_CTX *ctx, const unsigned char *buf, unsigned int len)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* Update bitcount */
|
||||
u_int32_t t = ctx->bytesLo;
|
||||
if ((ctx->bytesLo = t + len) < t)
|
||||
ctx->bytesHi++; /* Carry from low to high */
|
||||
|
||||
i = (unsigned) t % RIPEMD160_BLOCKBYTES; /* Bytes already in ctx->key */
|
||||
|
||||
/* i is always less than RIPEMD160_BLOCKBYTES. */
|
||||
if (RIPEMD160_BLOCKBYTES - i > len)
|
||||
{
|
||||
memcpy ((u_int8_t *) ctx->key + i, buf, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (i)
|
||||
{ /* First chunk is an odd size */
|
||||
memcpy ((u_int8_t *) ctx->key + i, buf, RIPEMD160_BLOCKBYTES - i);
|
||||
rmd160ByteSwap (ctx->key, (u_int8_t *) ctx->key, RIPEMD160_BLOCKWORDS);
|
||||
RMDcompress (ctx->iv, ctx->key);
|
||||
buf += RIPEMD160_BLOCKBYTES - i;
|
||||
len -= RIPEMD160_BLOCKBYTES - i;
|
||||
}
|
||||
|
||||
/* Process data in 64-byte chunks */
|
||||
while (len >= RIPEMD160_BLOCKBYTES)
|
||||
{
|
||||
rmd160ByteSwap (ctx->key, buf, RIPEMD160_BLOCKWORDS);
|
||||
RMDcompress (ctx->iv, ctx->key);
|
||||
buf += RIPEMD160_BLOCKBYTES;
|
||||
len -= RIPEMD160_BLOCKBYTES;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
if (len)
|
||||
memcpy (ctx->key, buf, len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Final wrapup - MD4 style padding on last block.
|
||||
*/
|
||||
void
|
||||
RMD160Final (unsigned char digest[20], RMD160_CTX * ctx)
|
||||
{
|
||||
int i;
|
||||
u_int32_t t;
|
||||
|
||||
RMDFinish (ctx->iv, (u_int8_t *) ctx->key, ctx->bytesLo, ctx->bytesHi);
|
||||
|
||||
for (i = 0; i < RIPEMD160_HASHWORDS; i++)
|
||||
{
|
||||
t = ctx->iv[i];
|
||||
digest[i * 4 + 0] = (u_int8_t) t;
|
||||
digest[i * 4 + 1] = (u_int8_t) (t >> 8);
|
||||
digest[i * 4 + 2] = (u_int8_t) (t >> 16);
|
||||
digest[i * 4 + 3] = (u_int8_t) (t >> 24);
|
||||
}
|
||||
|
||||
memset (ctx, 0, sizeof (RMD160_CTX)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
void RMD160Data(const unsigned char *buf, unsigned int len, char *out) {
|
||||
RMD160_CTX ctx;
|
||||
RMD160Init(&ctx);
|
||||
RMD160Update(&ctx,(unsigned char *)buf,len);
|
||||
RMD160Final((unsigned char *)out,&ctx);
|
||||
}
|
41
rmd160/rmd160.h
Normal file
41
rmd160/rmd160.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/* RMD160.H - header file for RMD160.C
|
||||
*/
|
||||
#ifndef _RMD160_H_
|
||||
#define _RMD160_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define RMD160_BLOCKBYTES 64
|
||||
#define RMD160_BLOCKWORDS 16
|
||||
|
||||
#define RMD160_HASHBYTES 20
|
||||
#define RMD160_HASHWORDS 5
|
||||
|
||||
/* For compatibility */
|
||||
#define RIPEMD160_BLOCKBYTES 64
|
||||
#define RIPEMD160_BLOCKWORDS 16
|
||||
|
||||
#define RIPEMD160_HASHBYTES 20
|
||||
#define RIPEMD160_HASHWORDS 5
|
||||
|
||||
/* RIPEMD160 context. */
|
||||
typedef struct RMD160Context {
|
||||
u_int32_t key[RIPEMD160_BLOCKWORDS];
|
||||
u_int32_t iv[RIPEMD160_HASHWORDS];
|
||||
u_int32_t bytesHi, bytesLo;
|
||||
} RMD160_CTX;
|
||||
|
||||
#define RIPEMD160Context RMD160Context
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
void RMD160Init(RMD160_CTX *);
|
||||
void RMD160Update(RMD160_CTX *, const unsigned char *, unsigned int);
|
||||
void RMD160Final(unsigned char [RMD160_HASHBYTES], RMD160_CTX *);
|
||||
char * RMD160End(RMD160_CTX *, char *);
|
||||
char * RMD160File(const char *, char *);
|
||||
void RMD160Data(const unsigned char *, unsigned int, char *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RMD160_H_ */
|
142
sha256/sha256.c
Normal file
142
sha256/sha256.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
SHA256 implementation, source file.
|
||||
|
||||
This implementation was written by Kent "ethereal" Williams-King and is
|
||||
hereby released into the public domain. Do what you wish with it.
|
||||
|
||||
No guarantees as to the correctness of the implementation are provided.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
const uint32_t sha256_initial_h[8]
|
||||
= { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
|
||||
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
|
||||
|
||||
const uint32_t sha256_round_k[64]
|
||||
= { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
||||
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
||||
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
||||
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
||||
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
||||
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
||||
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
||||
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
||||
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 };
|
||||
|
||||
void sha256_endian_reverse64(uint64_t input, uint8_t *output) {
|
||||
output[7] = (input >> 0) & 0xff;
|
||||
output[6] = (input >> 8) & 0xff;
|
||||
output[5] = (input >> 16) & 0xff;
|
||||
output[4] = (input >> 24) & 0xff;
|
||||
output[3] = (input >> 32) & 0xff;
|
||||
output[2] = (input >> 40) & 0xff;
|
||||
output[1] = (input >> 48) & 0xff;
|
||||
output[0] = (input >> 56) & 0xff;
|
||||
}
|
||||
|
||||
uint32_t sha256_endian_read32(uint8_t *input) {
|
||||
uint32_t output = 0;
|
||||
output |= (input[0] << 24);
|
||||
output |= (input[1] << 16);
|
||||
output |= (input[2] << 8);
|
||||
output |= (input[3] << 0);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void sha256_endian_reverse32(uint32_t input, uint8_t *output) {
|
||||
output[3] = (input >> 0) & 0xff;
|
||||
output[2] = (input >> 8) & 0xff;
|
||||
output[1] = (input >> 16) & 0xff;
|
||||
output[0] = (input >> 24) & 0xff;
|
||||
}
|
||||
|
||||
uint32_t sha256_ror(uint32_t input, uint32_t by) {
|
||||
return (input >> by) | (((input & ((1 << by) - 1))) << (32 - by));
|
||||
}
|
||||
|
||||
void sha256(const void *data, uint64_t len, void *output) {
|
||||
uint8_t padding[80];
|
||||
uint64_t current = (len + 1) % 64;
|
||||
// want to be == 56 % 64.
|
||||
uint64_t needed = (64 + 56 - current) % 64;
|
||||
uint64_t extra = needed + 9;
|
||||
uint64_t total = len + extra;
|
||||
|
||||
for(int i = 1; i < 80; i++)
|
||||
padding[i] = 0;
|
||||
padding[0] = 0x80;
|
||||
sha256_endian_reverse64(len * 8, padding + total - len - 8);
|
||||
|
||||
uint32_t v[8];
|
||||
for(int i = 0; i < 8; i++)
|
||||
v[i] = sha256_initial_h[i];
|
||||
|
||||
for(uint64_t cursor = 0; cursor * 64 < total; cursor++) {
|
||||
uint32_t t[8];
|
||||
for(int i = 0; i < 8; i++)
|
||||
t[i] = v[i];
|
||||
|
||||
uint32_t w[64];
|
||||
if(cursor * 64 + 64 <= len) {
|
||||
for(int j = 0; j < 16; j++) {
|
||||
w[j] = sha256_endian_read32(
|
||||
(uint8_t *)data + cursor * 64 + j * 4);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(cursor * 64 < len) {
|
||||
uint64_t size = len - cursor * 64;
|
||||
if(size > 0) memcpy(w, (uint8_t *)data + cursor * 64, size);
|
||||
memcpy((uint8_t *)w + size, padding, 64 - size);
|
||||
}
|
||||
else {
|
||||
uint64_t off = (cursor * 64 - len) % 64;
|
||||
memcpy((uint8_t *)w, padding + off, 64);
|
||||
}
|
||||
|
||||
for(int j = 0; j < 16; j++) {
|
||||
w[j] = sha256_endian_read32((uint8_t *)&w[j]);
|
||||
}
|
||||
}
|
||||
|
||||
for(int j = 16; j < 64; j++) {
|
||||
uint32_t s1 = sha256_ror(w[j - 2], 17) ^ sha256_ror(w[j - 2], 19)
|
||||
^ (w[j - 2] >> 10);
|
||||
uint32_t s0 = sha256_ror(w[j - 15], 7) ^ sha256_ror(w[j - 15], 18)
|
||||
^ (w[j - 15] >> 3);
|
||||
w[j] = s1 + w[j - 7] + s0 + w[j - 16];
|
||||
}
|
||||
|
||||
for(int j = 0; j < 64; j++) {
|
||||
uint32_t ch = (t[4] & t[5]) ^ (~t[4] & t[6]);
|
||||
uint32_t maj = (t[0] & t[1]) ^ (t[0] & t[2]) ^ (t[1] & t[2]);
|
||||
uint32_t S0 = sha256_ror(t[0], 2) ^ sha256_ror(t[0], 13)
|
||||
^ sha256_ror(t[0], 22);
|
||||
uint32_t S1 = sha256_ror(t[4], 6) ^ sha256_ror(t[4], 11)
|
||||
^ sha256_ror(t[4], 25);
|
||||
|
||||
uint32_t t1 = t[7] + S1 + ch + sha256_round_k[j] + w[j];
|
||||
uint32_t t2 = S0 + maj;
|
||||
|
||||
t[7] = t[6];
|
||||
t[6] = t[5];
|
||||
t[5] = t[4];
|
||||
t[4] = t[3] + t1;
|
||||
t[3] = t[2];
|
||||
t[2] = t[1];
|
||||
t[1] = t[0];
|
||||
t[0] = t1 + t2;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
v[i] += t[i];
|
||||
}
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
sha256_endian_reverse32(v[i], (uint8_t *)output + i * 4);
|
||||
}
|
17
sha256/sha256.h
Normal file
17
sha256/sha256.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
SHA256 implementation, header file.
|
||||
|
||||
This implementation was written by Kent "ethereal" Williams-King and is
|
||||
hereby released into the public domain. Do what you wish with it.
|
||||
|
||||
No guarantees as to the correctness of the implementation are provided.
|
||||
*/
|
||||
|
||||
#ifndef SHA256_H
|
||||
#define SHA256_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void sha256(const void *data, uint64_t len, void *output);
|
||||
|
||||
#endif
|
186
util.h
Normal file
186
util.h
Normal file
@@ -0,0 +1,186 @@
|
||||
typedef struct str_list {
|
||||
int n;
|
||||
char **data;
|
||||
int *lengths;
|
||||
}List;
|
||||
|
||||
typedef struct str_tokenizer {
|
||||
int current;
|
||||
int n;
|
||||
char **tokens;
|
||||
}Tokenizer;
|
||||
|
||||
char *ltrim(char *str, const char *seps);
|
||||
char *rtrim(char *str, const char *seps);
|
||||
char *trim(char *str, const char *seps);
|
||||
int indexOf(char *s,const char **array,int length_array);
|
||||
|
||||
int hexchr2bin(char hex, char *out);
|
||||
int hexs2bin(char *hex, unsigned char *out);
|
||||
char *tohex(char *ptr,int length);
|
||||
|
||||
int hasMoreTokens(Tokenizer *t);
|
||||
char *nextToken(Tokenizer *t);
|
||||
|
||||
char *ltrim(char *str, const char *seps) {
|
||||
size_t totrim;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
totrim = strspn(str, seps);
|
||||
if (totrim > 0) {
|
||||
size_t len = strlen(str);
|
||||
if (totrim == len) {
|
||||
str[0] = '\0';
|
||||
}
|
||||
else {
|
||||
memmove(str, str + totrim, len + 1 - totrim);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *rtrim(char *str, const char *seps) {
|
||||
int i;
|
||||
if (seps == NULL) {
|
||||
seps = "\t\n\v\f\r ";
|
||||
}
|
||||
i = strlen(str) - 1;
|
||||
while (i >= 0 && strchr(seps, str[i]) != NULL) {
|
||||
str[i] = '\0';
|
||||
i--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
char *trim(char *str, const char *seps) {
|
||||
return ltrim(rtrim(str, seps), seps);
|
||||
}
|
||||
|
||||
int indexOf(char *s,const char **array,int length_array) {
|
||||
int index = -1,i,continuar = 1;
|
||||
for(i = 0; i <length_array && continuar; i++) {
|
||||
if(strcmp(s,array[i]) == 0) {
|
||||
index = i;
|
||||
continuar = 0;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
char *nextToken(Tokenizer *t) {
|
||||
if(t->current < t->n) {
|
||||
t->current++;
|
||||
return t->tokens[t->current-1];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
int hasMoreTokens(Tokenizer *t) {
|
||||
return (t->current < t->n);
|
||||
}
|
||||
|
||||
void stringtokenizer(char *data,Tokenizer *t) {
|
||||
char *token;
|
||||
t->tokens = NULL;
|
||||
t->n = 0;
|
||||
t->current = 0;
|
||||
trim(data,"\t\n\r ");
|
||||
token = strtok(data," \t:");
|
||||
while(token != NULL) {
|
||||
t->n++;
|
||||
t->tokens = realloc(t->tokens,sizeof(char*)*t->n);
|
||||
if(t->tokens == NULL) {
|
||||
printf("Out of memory\n");
|
||||
exit(0);
|
||||
}
|
||||
t->tokens[t->n - 1] = token;
|
||||
token = strtok(NULL," \t");
|
||||
}
|
||||
}
|
||||
|
||||
void freetokenizer(Tokenizer *t) {
|
||||
if(t->n > 0) {
|
||||
free(t-> tokens);
|
||||
}
|
||||
memset(t,0,sizeof(Tokenizer));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aux function to get the hexvalues of the data
|
||||
*/
|
||||
|
||||
char *tohex(char *ptr,int length){
|
||||
char *buffer;
|
||||
int offset = 0;
|
||||
unsigned char c;
|
||||
buffer = (char *) malloc((length * 2)+1);
|
||||
for (int i = 0; i <length; i++) {
|
||||
c = ptr[i];
|
||||
sprintf((char*) (buffer + offset),"%.2x",c);
|
||||
offset+=2;
|
||||
}
|
||||
buffer[length*2] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
int hexs2bin(char *hex, unsigned char *out) {
|
||||
int len;
|
||||
char b1;
|
||||
char b2;
|
||||
int i;
|
||||
|
||||
if (hex == NULL || *hex == '\0' || out == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(hex);
|
||||
if (len % 2 != 0)
|
||||
return 0;
|
||||
len /= 2;
|
||||
|
||||
memset(out, 'A', len);
|
||||
for (i=0; i<len; i++) {
|
||||
if (!hexchr2bin(hex[i*2], &b1) || !hexchr2bin(hex[i*2+1], &b2)) {
|
||||
return 0;
|
||||
}
|
||||
out[i] = (b1 << 4) | b2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int hexchr2bin(const char hex, char *out) {
|
||||
if (out == NULL)
|
||||
return 0;
|
||||
|
||||
if (hex >= '0' && hex <= '9') {
|
||||
*out = hex - '0';
|
||||
} else if (hex >= 'A' && hex <= 'F') {
|
||||
*out = hex - 'A' + 10;
|
||||
} else if (hex >= 'a' && hex <= 'f') {
|
||||
*out = hex - 'a' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void addItemList(char *data, List *l) {
|
||||
l->data = realloc(l->data,sizeof(char*)* (l->n +1));
|
||||
l->data[l->n] = data;
|
||||
l->n++;
|
||||
}
|
||||
|
||||
int isValidHex(char *data) {
|
||||
char c;
|
||||
int len,i,valid = 1;
|
||||
len = strlen(data);
|
||||
for(i = 0 ; i < len && valid ;i++ ) {
|
||||
c = data[i];
|
||||
valid = ( (c >= '0' && c <='9') || (c >= 'A' && c <='F' ) || (c >= 'a' && c <='f' ) );
|
||||
}
|
||||
return valid;
|
||||
}
|
Reference in New Issue
Block a user