librhash 2019-12-14 (75716b45)

Code extracted from:

    https://github.com/rhash/rhash.git

at commit 75716b45c21416c98c0ab2e3c2735b150e7afb03 (v1.3.9).
This commit is contained in:
librhash upstream
2019-12-14 19:52:11 +03:00
committed by Brad King
parent 7fcbd47e95
commit 641cc0030c
22 changed files with 948 additions and 757 deletions
+11 -11
View File
@@ -1,15 +1,15 @@
RHash License
BSD Zero Clause License
Copyright (c) 2005-2014 Aleksey Kravchenko <rhash.admin@gmail.com>
Copyright (c) 2005, Aleksey Kravchenko <rhash.admin@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
The Software is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. Use this program at your own risk!
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
-61
View File
@@ -1,61 +0,0 @@
=== RHash program ===
RHash is a console utility for calculation and verification of magnet links
and a wide range of hash sums like CRC32, MD4, MD5, SHA1, SHA256, SHA512,
SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94,
RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru.
Hash sums are used to ensure and verify integrity of large volumes of data
for a long-term storing or transferring.
Features:
* Output in a predefined (SFV, BSD-like) or a user-defined format.
* Can calculate Magnet links.
* Updating hash files (adding hash sums of files missing in the hash file).
* Calculates several hash sums in one pass
* Ability to process directories recursively.
* Portability: the program works the same on Linux, *BSD or Windows.
=== The LibRHash library ===
LibRHash is a professional, portable, thread-safe C library for computing
a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512,
SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94,
RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru.
Hash sums are used to ensure and verify integrity of large volumes of data
for a long-term storing or transferring.
Features:
* Small and easy to learn interface.
* Hi-level and Low-level API.
* Allows calculating of several hash functions simultaneously.
* Portability: the library works on Linux, *BSD and Windows.
=== Links ===
* Project Home Page: http://rhash.sourceforge.net/
* Official Releases: http://sf.net/projects/rhash/files/rhash/
* RHash hash functions descriptions http://rhash.anz.ru/hashes.php
* The table of the hash functions supported by RHash
http://sf.net/apps/mediawiki/rhash/index.php?title=Hash_sums
* ECRYPT: The Hash Function Zoo
http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo
=== Getting latest source code ===
The latest source code can be obtained from Git repository by command:
git clone git://github.com/rhash/RHash.git
=== Notes on RHash License ===
The RHash program and LibRHash library are distributed under RHash License,
see the COPYING file for details. In particular, the program, the library
and source code can be used free of charge under the MIT, BSD, GPL,
commercial or freeware license without additional restrictions. In the case
the OSI-approved license is required the MIT license should be used.
+102 -42
View File
@@ -1,17 +1,17 @@
/* algorithms.c - the algorithms supported by the rhash library
*
* Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2011, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <stdio.h>
@@ -26,7 +26,8 @@
#include "crc32.h"
#include "ed2k.h"
#include "edonr.h"
#include "gost.h"
#include "gost12.h"
#include "gost94.h"
#include "has160.h"
#include "md4.h"
#include "md5.h"
@@ -49,18 +50,13 @@
#else
# define NEED_OPENSSL_INIT 0
#endif /* USE_OPENSSL */
#ifdef GENERATE_GOST_LOOKUP_TABLE
# define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO)
#ifdef GENERATE_GOST94_LOOKUP_TABLE
# define NEED_GOST94_INIT (RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO)
#else
# define NEED_GOST_INIT 0
#endif /* GENERATE_GOST_LOOKUP_TABLE */
#ifdef GENERATE_CRC32_TABLE
# define NEED_CRC32_INIT RHASH_CRC32
#else
# define NEED_CRC32_INIT 0
#endif /* GENERATE_CRC32_TABLE */
# define NEED_GOST94_INIT 0
#endif /* GENERATE_GOST94_LOOKUP_TABLE */
#define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_INIT | NEED_OPENSSL_INIT)
#define RHASH_NEED_INIT_ALG (NEED_GOST94_INIT | NEED_OPENSSL_INIT)
unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG;
rhash_hash_info* rhash_info_table = rhash_hash_info_default;
@@ -69,8 +65,12 @@ int rhash_info_size = RHASH_HASH_COUNT;
static void rhash_crc32_init(uint32_t* crc32);
static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size);
static void rhash_crc32_final(uint32_t* crc32, unsigned char* result);
static void rhash_crc32c_init(uint32_t* crc32);
static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size);
static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result);
rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
rhash_info info_crc32c = { RHASH_CRC32C, F_BE32, 4, "CRC32C", "crc32c" };
rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" };
rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" };
@@ -81,8 +81,10 @@ rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" };
rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" };
rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" };
rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" };
rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" };
rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" };
rhash_info info_gost12_256 = { RHASH_GOST12_256, F_LE64, 32, "GOST12-256", "gost12-256" };
rhash_info info_gost12_512 = { RHASH_GOST12_512, F_LE64, 64, "GOST12-512", "gost12-512" };
rhash_info info_gost94 = { RHASH_GOST94, F_LE32, 32, "GOST94", "gost94" };
rhash_info info_gost94pro = { RHASH_GOST94_CRYPTOPRO, F_LE32, 32, "GOST94-CRYPTOPRO", "gost94-cryptopro" };
rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" };
rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" };
rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" };
@@ -104,9 +106,10 @@ rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512"
#define upd(name) ((pupdate_t)(name##_update))
#define fin(name) ((pfinal_t)(name##_final))
#define iuf(name) ini(name), upd(name), fin(name)
#define iuf2(name1, name2) ini(name1), upd(name2), fin(name2)
#define diuf(name) dgshft(name), ini(name), upd(name), fin(name)
/* information about all hashes */
/* information about all supported hash functions */
rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
{
{ &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */
@@ -120,25 +123,30 @@ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
{ &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */
{ &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */
{ &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */
{ &info_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */
{ &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */
{ &info_gost94, sizeof(gost94_ctx), dgshft(gost94), iuf(rhash_gost94), 0 }, /* 256 bit */
{ &info_gost94pro, sizeof(gost94_ctx), dgshft(gost94), iuf2(rhash_gost94_cryptopro, rhash_gost94), 0 }, /* 256 bit */
{ &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */
{ &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */
{ &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */
{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(rhash_sha256), 0 }, /* 224 bit */
{ &info_gost12_256, sizeof(gost12_ctx), dgshft2(gost12, h) + 32, iuf2(rhash_gost12_256, rhash_gost12), 0 }, /* 256 bit */
{ &info_gost12_512, sizeof(gost12_ctx), dgshft2(gost12, h), iuf2(rhash_gost12_512, rhash_gost12), 0 }, /* 512 bit */
{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), iuf2(rhash_sha224, rhash_sha256), 0 }, /* 224 bit */
{ &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */
{ &info_sha384, sizeof(sha512_ctx), dgshft(sha512), ini(rhash_sha384), upd(rhash_sha512), fin(rhash_sha512), 0 }, /* 384 bit */
{ &info_sha384, sizeof(sha512_ctx), dgshft(sha512), iuf2(rhash_sha384, rhash_sha512), 0 }, /* 384 bit */
{ &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */
{ &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */
{ &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */
{ &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */
{ &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */
{ &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */
{ &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */
{ &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */
{ &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */
{ &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_224, rhash_sha3), 0 }, /* 224 bit */
{ &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_256, rhash_sha3), 0 }, /* 256 bit */
{ &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_384, rhash_sha3), 0 }, /* 384 bit */
{ &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_512, rhash_sha3), 0 }, /* 512 bit */
{ &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */
{ &info_snf128, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru128, rhash_snefru), 0 }, /* 128 bit */
{ &info_snf256, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru256, rhash_snefru), 0 }, /* 256 bit */
};
/**
* Initialize requested algorithms.
*
* @param mask ids of hash sums to initialize
*/
void rhash_init_algorithms(unsigned mask)
{
@@ -147,15 +155,26 @@ void rhash_init_algorithms(unsigned mask)
/* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */
assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1)));
#ifdef GENERATE_CRC32_TABLE
rhash_crc32_init_table();
#endif
#ifdef GENERATE_GOST_LOOKUP_TABLE
rhash_gost_init_table();
#ifdef GENERATE_GOST94_LOOKUP_TABLE
rhash_gost94_init_table();
#endif
rhash_uninitialized_algorithms = 0;
}
/**
* Returns information about a hash function by its hash_id.
*
* @param hash_id the id of hash algorithm
* @return pointer to the rhash_info structure containing the information
*/
const rhash_info* rhash_info_by_id(unsigned hash_id)
{
hash_id &= RHASH_ALL_HASHES;
/* check that one and only one bit is set */
if (!hash_id || (hash_id & (hash_id - 1)) != 0) return NULL;
return rhash_info_table[rhash_ctz(hash_id)].info;
}
/* CRC32 helper functions */
/**
@@ -198,3 +217,44 @@ static void rhash_crc32_final(uint32_t* crc32, unsigned char* result)
result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
#endif
}
/**
* Initialize crc32c hash.
*
* @param crc32c pointer to the hash to initialize
*/
static void rhash_crc32c_init(uint32_t* crc32c)
{
*crc32c = 0; /* note: context size is sizeof(uint32_t) */
}
/**
* Calculate message CRC32C hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param crc32c pointer to the hash
* @param msg message chunk
* @param size length of the message chunk
*/
static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size)
{
*crc32c = rhash_get_crc32c(*crc32c, msg, size);
}
/**
* Store calculated hash into the given array.
*
* @param crc32c pointer to the current hash value
* @param result calculated hash in binary form
*/
static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result)
{
#if defined(CPU_IA32) || defined(CPU_X64)
/* intel CPUs support assigment with non 32-bit aligned pointers */
*(unsigned*)result = be2me_32(*crc32c);
#else
/* correct saving BigEndian integer on all archs */
result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16);
result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c);
#endif
}
+42 -7
View File
@@ -2,9 +2,9 @@
#ifndef RHASH_ALGORITHMS_H
#define RHASH_ALGORITHMS_H
#include <stddef.h> /* for ptrdiff_t */
#include "rhash.h"
#include "byte_order.h"
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
@@ -15,8 +15,40 @@ extern "C" {
# define RHASH_API
#endif
/**
* Bit flag: default hash output format is base32.
*/
#define RHASH_INFO_BASE32 1
/**
* Information about a hash function.
*/
typedef struct rhash_info
{
/**
* Hash function indentifier.
*/
unsigned hash_id;
/**
* Flags bit-mask, including RHASH_INFO_BASE32 bit.
*/
unsigned flags;
/**
The size of of the raw message digest in bytes.
*/
size_t digest_size;
/**
* The hash function name.
*/
const char* name;
/**
* The corresponding paramenter name in a magnet link.
*/
const char* magnet_name;
} rhash_info;
typedef void (*pinit_t)(void*);
typedef void (*pupdate_t)(void *ctx, const void* msg, size_t size);
typedef void (*pupdate_t)(void* ctx, const void* msg, size_t size);
typedef void (*pfinal_t)(void*, unsigned char*);
typedef void (*pcleanup_t)(void*);
@@ -25,7 +57,7 @@ typedef void (*pcleanup_t)(void*);
*/
typedef struct rhash_hash_info
{
rhash_info *info;
rhash_info* info;
size_t context_size;
ptrdiff_t digest_diff;
pinit_t init;
@@ -40,7 +72,7 @@ typedef struct rhash_hash_info
typedef struct rhash_vector_item
{
struct rhash_hash_info* hash_info;
void *context;
void* context;
} rhash_vector_item;
/**
@@ -52,8 +84,9 @@ typedef struct rhash_context_ext
unsigned hash_vector_size; /* number of contained hash sums */
unsigned flags;
unsigned state;
void *callback, *callback_data;
void *bt_ctx;
void* callback;
void* callback_data;
void* bt_ctx;
rhash_vector_item vector[1]; /* contexts of contained hash sums */
} rhash_context_ext;
@@ -63,6 +96,7 @@ extern int rhash_info_size;
extern unsigned rhash_uninitialized_algorithms;
extern rhash_info info_crc32;
extern rhash_info info_crc32c;
extern rhash_info info_md4;
extern rhash_info info_md5;
extern rhash_info info_sha1;
@@ -95,7 +129,7 @@ extern rhash_info info_edr512;
#define F_SWAP64 4
/* define endianness flags */
#ifndef CPU_BIG_ENDIAN
#if IS_LITTLE_ENDIAN
#define F_LE32 0
#define F_LE64 0
#define F_BE32 F_SWAP32
@@ -108,6 +142,7 @@ extern rhash_info info_edr512;
#endif
void rhash_init_algorithms(unsigned mask);
const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
#if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL)
# define USE_OPENSSL
+38 -15
View File
@@ -1,21 +1,21 @@
/* byte_order.c - byte order related platform dependent routines,
*
* Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "byte_order.h"
#if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */
#ifndef rhash_ctz
# if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */
# include <intrin.h>
@@ -59,7 +59,7 @@ unsigned rhash_ctz(unsigned x)
return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
}
# endif /* _MSC_VER >= 1300... */
#endif /* !(GCC >= 4.3) */
#endif /* rhash_ctz */
/**
* Copy a memory block with simultaneous exchanging byte order.
@@ -79,10 +79,12 @@ void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t le
const uint32_t* src = (const uint32_t*)from;
const uint32_t* end = (const uint32_t*)((const char*)src + length);
uint32_t* dst = (uint32_t*)((char*)to + index);
while (src < end) *(dst++) = bswap_32( *(src++) );
for (; src < end; dst++, src++)
*dst = bswap_32(*src);
} else {
const char* src = (const char*)from;
for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 3] = *(src++);
for (length += index; (size_t)index < length; index++)
((char*)to)[index ^ 3] = *(src++);
}
}
@@ -141,10 +143,31 @@ void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length)
* @param arr the array to process
* @param length array length
*/
void rhash_u32_mem_swap(unsigned *arr, int length)
void rhash_u32_mem_swap(unsigned* arr, int length)
{
unsigned* end = arr + length;
for (; arr < end; arr++) {
*arr = bswap_32(*arr);
}
}
#ifdef HAS_INTEL_CPUID
#include <cpuid.h>
static uint64_t get_cpuid_features(void)
{
uint32_t tmp, edx, ecx;
if (__get_cpuid(1, &tmp, &tmp, &ecx, &edx))
return ((((uint64_t)ecx) << 32) ^ edx);
return 0;
}
int has_cpu_feature(unsigned feature_bit)
{
static uint64_t features;
const uint64_t feature = ((uint64_t)1) << feature_bit;
if (!features)
features = (get_cpuid_features() | 1);
return !!(features & feature);
}
#endif
+97 -61
View File
@@ -4,13 +4,15 @@
#include "ustd.h"
#include <stdlib.h>
#ifdef IN_RHASH
#include "config.h"
#endif
#ifdef __GLIBC__
#if defined(__GLIBC__)
# include <endian.h>
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
# include <sys/types.h>
#elif defined (__NetBSD__) || defined(__OpenBSD__)
# include <sys/param.h>
#endif
#ifdef __cplusplus
extern "C" {
@@ -34,29 +36,49 @@ extern "C" {
# endif
#endif
#define RHASH_BYTE_ORDER_LE 1234
#define RHASH_BYTE_ORDER_BE 4321
/* detect CPU endianness */
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
__BYTE_ORDER == __LITTLE_ENDIAN) || \
defined(CPU_IA32) || defined(CPU_X64) || \
defined(__ia64) || defined(__ia64__) || defined(__alpha__) || defined(_M_ALPHA) || \
defined(vax) || defined(MIPSEL) || defined(_ARM_) || defined(__arm__)
# define CPU_LITTLE_ENDIAN
# define IS_BIG_ENDIAN 0
# define IS_LITTLE_ENDIAN 1
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
__BYTE_ORDER == __BIG_ENDIAN) || \
defined(__sparc) || defined(__sparc__) || defined(sparc) || \
defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \
defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \
defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \
defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \
defined(__s390__) || defined(__s390x__) || defined(sel)
# define CPU_BIG_ENDIAN
# define IS_BIG_ENDIAN 1
# define IS_LITTLE_ENDIAN 0
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
#elif defined(_BYTE_ORDER)
# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
# elif defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
# endif
#elif defined(__sun) && defined(_LITTLE_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
#elif defined(__sun) && defined(_BIG_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
#endif
/* try detecting endianness by CPU */
#ifdef RHASH_BYTE_ORDER
#elif defined(CPU_IA32) || defined(CPU_X64) || defined(__ia64) || defined(__ia64__) || \
defined(__alpha__) || defined(_M_ALPHA) || defined(vax) || defined(MIPSEL) || \
defined(_ARM_) || defined(__arm__)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
#elif defined(__sparc) || defined(__sparc__) || defined(sparc) || \
defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \
defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \
defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \
defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \
defined(__s390__) || defined(__s390x__) || defined(sel)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
#else
# error "Can't detect CPU architechture"
# error "Can't detect CPU architechture"
#endif
#define IS_BIG_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_BE)
#define IS_LITTLE_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_LE)
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
#define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0)))
@@ -74,11 +96,23 @@ extern "C" {
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define I64(x) x##ui64
#else
#define I64(x) x##LL
#define I64(x) x##ULL
#endif
/* convert a hash flag to index */
#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */
#if defined(_MSC_VER)
#define RHASH_INLINE __inline
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define RHASH_INLINE inline
#elif defined(__GNUC__)
#define RHASH_INLINE __inline__
#else
#define RHASH_INLINE
#endif
/* define rhash_ctz - count traling zero bits */
#if (defined(__GNUC__) && __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) || \
(defined(__clang__) && __has_builtin(__builtin_ctz))
/* GCC >= 3.4 or clang */
# define rhash_ctz(x) __builtin_ctz(x)
#else
unsigned rhash_ctz(unsigned); /* define as function */
@@ -87,37 +121,31 @@ unsigned rhash_ctz(unsigned); /* define as function */
void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length);
void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length);
void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length);
void rhash_u32_mem_swap(unsigned *p, int length_in_u32);
void rhash_u32_mem_swap(unsigned* p, int length_in_u32);
/* define bswap_32 */
#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__)
/* for intel x86 CPU */
static inline uint32_t bswap_32(uint32_t x) {
__asm("bswap\t%0" : "=r" (x) : "0" (x));
return x;
}
#elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
/* for GCC >= 4.3 */
/* bswap definitions */
#if (defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) || \
(defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64))
/* GCC >= 4.3 or clang */
# define bswap_32(x) __builtin_bswap32(x)
#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
# define bswap_32(x) _byteswap_ulong((unsigned long)x)
#elif !defined(__STRICT_ANSI__)
/* general bswap_32 definition */
static inline uint32_t bswap_32(uint32_t x) {
x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF);
return (x >> 16) | (x << 16);
}
#else
#define bswap_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#endif /* bswap_32 */
#if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)
# define bswap_64(x) __builtin_bswap64(x)
#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
# define bswap_32(x) _byteswap_ulong((unsigned long)x)
# define bswap_64(x) _byteswap_uint64((__int64)x)
#elif !defined(__STRICT_ANSI__)
static inline uint64_t bswap_64(uint64_t x) {
#else
/* fallback to generic bswap definition */
static RHASH_INLINE uint32_t bswap_32(uint32_t x)
{
# if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) && !defined(RHASH_NO_ASM)
__asm("bswap\t%0" : "=r" (x) : "0" (x)); /* gcc x86 version */
return x;
# else
x = ((x << 8) & 0xFF00FF00u) | ((x >> 8) & 0x00FF00FFu);
return (x >> 16) | (x << 16);
# endif
}
static RHASH_INLINE uint64_t bswap_64(uint64_t x)
{
union {
uint64_t ll;
uint32_t l[2];
@@ -127,11 +155,9 @@ static inline uint64_t bswap_64(uint64_t x) {
r.l[1] = bswap_32(w.l[0]);
return r.ll;
}
#else
#error "bswap_64 unsupported"
#endif
#endif /* bswap definitions */
#ifdef CPU_BIG_ENDIAN
#if IS_BIG_ENDIAN
# define be2me_32(x) (x)
# define be2me_64(x) (x)
# define le2me_32(x) bswap_32(x)
@@ -144,7 +170,7 @@ static inline uint64_t bswap_64(uint64_t x) {
# define me64_to_be_str(to, from, length) memcpy((to), (from), (length))
# define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
#else /* CPU_BIG_ENDIAN */
#else /* IS_BIG_ENDIAN */
# define be2me_32(x) bswap_32(x)
# define be2me_64(x) bswap_64(x)
# define le2me_32(x) (x)
@@ -156,7 +182,7 @@ static inline uint64_t bswap_64(uint64_t x) {
# define le64_copy(to, index, from, length) memcpy((to) + (index), (from), (length))
# define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
# define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
#endif /* CPU_BIG_ENDIAN */
#endif /* IS_BIG_ENDIAN */
/* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */
#define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))
@@ -164,6 +190,16 @@ static inline uint64_t bswap_64(uint64_t x) {
#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
#define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n))))
#define CPU_FEATURE_SSE4_2 (52)
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) \
&& (defined(CPU_X64) || defined(CPU_IA32))
# define HAS_INTEL_CPUID
int has_cpu_feature(unsigned feature_bit);
#else
# define has_cpu_feature(x) (0)
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
+96 -74
View File
@@ -1,71 +1,57 @@
/* hex.c - conversion for hexadecimal and base32 strings.
*
* Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
#include <ctype.h>
#include "hex.h"
/**
* Convert a byte to a hexadecimal number. The result, consisting of two
* hexadecimal digits is stored into a buffer.
*
* @param dest the buffer to receive two symbols of hex representation
* @param byte the byte to decode
* @param upper_case flag to print string in uppercase
* @return pointer to the chararcter just after the written number (dest + 2)
*/
char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case)
{
const char add = (upper_case ? 'A' - 10 : 'a' - 10);
unsigned char c = (byte >> 4) & 15;
*dest++ = (c > 9 ? c + add : c + '0');
c = byte & 15;
*dest++ = (c > 9 ? c + add : c + '0');
return dest;
}
#include <assert.h>
#include <ctype.h>
#include <string.h>
/**
* Store hexadecimal representation of a binary string to given buffer.
*
* @param dest the buffer to receive hexadecimal representation
* @param dst the buffer to receive hexadecimal representation
* @param src binary string
* @param len string length
* @param length string length
* @param upper_case flag to print string in uppercase
*/
void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case)
void rhash_byte_to_hex(char* dst, const unsigned char* src, size_t length, int upper_case)
{
while (len-- > 0) {
dest = rhash_print_hex_byte(dest, *src++, upper_case);
const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10);
for (; length > 0; src++, length--) {
const unsigned char hi = (*src >> 4) & 15;
const unsigned char lo = *src & 15;
*dst++ = (hi > 9 ? hi + hex_add : hi + '0');
*dst++ = (lo > 9 ? lo + hex_add : lo + '0');
}
*dest = '\0';
*dst = '\0';
}
/**
* Encode a binary string to base32.
*
* @param dest the buffer to store result
* @param dst the buffer to store result
* @param src binary string
* @param len string length
* @param length string length
* @param upper_case flag to print string in uppercase
*/
void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case)
void rhash_byte_to_base32(char* dst, const unsigned char* src, size_t length, int upper_case)
{
const char a = (upper_case ? 'A' : 'a');
unsigned shift = 0;
unsigned char word;
const unsigned char* e = src + len;
const unsigned char* e = src + length;
while (src < e) {
if (shift > 3) {
word = (*src & (0xFF >> shift));
@@ -79,25 +65,25 @@ void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, in
word = ( *src >> ( (8 - shift) & 7 ) ) & 0x1F;
if (shift == 0) src++;
}
*dest++ = ( word < 26 ? word + a : word + '2' - 26 );
*dst++ = ( word < 26 ? word + a : word + '2' - 26 );
}
*dest = '\0';
*dst = '\0';
}
/**
* Encode a binary string to base64.
* Encoded output length is always a multiple of 4 bytes.
*
* @param dest the buffer to store result
* @param dst the buffer to store result
* @param src binary string
* @param len string length
* @param length string length
*/
void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len)
void rhash_byte_to_base64(char* dst, const unsigned char* src, size_t length)
{
static const char* tail = "0123456789+/";
unsigned shift = 0;
unsigned char word;
const unsigned char* e = src + len;
const unsigned char* e = src + length;
while (src < e) {
if (shift > 2) {
word = (*src & (0xFF >> shift));
@@ -111,45 +97,80 @@ void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len)
word = ( *src >> ( (8 - shift) & 7 ) ) & 0x3F;
if (shift == 0) src++;
}
*dest++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]);
*dst++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]);
}
if (shift > 0) {
*dest++ = '=';
if (shift == 4) *dest++ = '=';
*dst++ = '=';
if (shift == 4) *dst++ = '=';
}
*dest = '\0';
*dst = '\0';
}
/* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */
#define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c))
size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case)
{
#define B64_CHUNK_SIZE 120
char buffer[164];
assert((BASE64_LENGTH(B64_CHUNK_SIZE) + 4) <= sizeof(buffer));
assert((B64_CHUNK_SIZE % 6) == 0);
if (url_encode) {
size_t result_length = 0;
for (; length > 0; src += B64_CHUNK_SIZE) {
size_t chunk_size = (length < B64_CHUNK_SIZE ? length : B64_CHUNK_SIZE);
size_t encoded_length;
rhash_byte_to_base64(buffer, src, chunk_size);
encoded_length = rhash_urlencode(dst, buffer, BASE64_LENGTH(chunk_size), upper_case);
result_length += encoded_length;
dst += encoded_length;
length -= chunk_size;
}
return result_length;
}
rhash_byte_to_base64(dst, src, length);
return BASE64_LENGTH(length);
}
/* RFC 3986: safe url characters are ascii alpha-numeric and "-._~", other characters should be percent-encoded */
static unsigned url_safe_char_mask[4] = { 0, 0x03ff6000, 0x87fffffe, 0x47fffffe };
#define IS_URL_GOOD_CHAR(c) ((unsigned)(c) < 128 && (url_safe_char_mask[c >> 5] & (1 << (c & 31))))
/**
* URL-encode a string.
* URL-encode specified binary string.
*
* @param dst buffer to receive result or NULL to calculate
* the lengths of encoded string
* @param filename the file name
* @param dst (nullable) buffer to output encoded string to,
* NULL to just calculate the lengths of encoded string
* @param src binary string to encode
* @param size size of the binary string
* @param upper_case flag to output hex-codes in uppercase
* @return the length of the result string
*/
int rhash_urlencode(char *dst, const char *name)
size_t rhash_urlencode(char* dst, const char* src, size_t size, int upper_case)
{
const char *start;
const char* start;
size_t i;
if (!dst) {
int len;
for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3);
return len;
}
/* encode URL as specified by RFC 1738 */
for (start = dst; *name; name++) {
if ( IS_GOOD_URL_CHAR(*name) ) {
*dst++ = *name;
} else {
*dst++ = '%';
dst = rhash_print_hex_byte(dst, *name, 'A');
size_t length = size;
for (i = 0; i < size; i++)
if (!IS_URL_GOOD_CHAR(src[i]))
length += 2;
return length;
} else {
const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10);
start = dst;
/* percent-encode all but unreserved URL characters */
for (i = 0; i < size; i++) {
if (IS_URL_GOOD_CHAR(src[i])) {
*dst++ = src[i];
} else {
unsigned char hi = ((unsigned char)(src[i]) >> 4) & 0x0f;
unsigned char lo = (unsigned char)(src[i]) & 0x0f;
*dst++ = '%';
*dst++ = (hi > 9 ? hi + hex_add : hi + '0');
*dst++ = (lo > 9 ? lo + hex_add : lo + '0');
}
}
*dst = 0;
}
*dst = 0;
return (int)(dst - start);
return dst - start;
}
/**
@@ -160,10 +181,11 @@ int rhash_urlencode(char *dst, const char *name)
* @param number the number to print
* @return length of the printed number (without trailing '\0')
*/
int rhash_sprintI64(char *dst, uint64_t number)
int rhash_sprintI64(char* dst, uint64_t number)
{
/* The biggest number has 20 digits: 2^64 = 18 446 744 073 709 551 616 */
char buf[24], *p;
char buf[24];
char* p;
size_t length;
if (dst == NULL) {
+7 -6
View File
@@ -8,12 +8,13 @@
extern "C" {
#endif
void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case);
void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case);
void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len);
char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case);
int rhash_urlencode(char *dst, const char *name);
int rhash_sprintI64(char *dst, uint64_t number);
void rhash_byte_to_hex(char* dest, const unsigned char* src, size_t length, int upper_case);
void rhash_byte_to_base32(char* dest, const unsigned char* src, size_t length, int upper_case);
void rhash_byte_to_base64(char* dest, const unsigned char* src, size_t length);
char* rhash_print_hex_byte(char* dest, const unsigned char byte, int upper_case);
size_t rhash_urlencode(char* dst, const char* str, size_t size, int upper_case);
size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case);
int rhash_sprintI64(char* dst, uint64_t number);
#define BASE32_LENGTH(bytes) (((bytes) * 8 + 4) / 5)
#define BASE64_LENGTH(bytes) ((((bytes) + 2) / 3) * 4)
+15 -15
View File
@@ -1,17 +1,17 @@
/* md5.c - an implementation of the MD5 algorithm, based on RFC 1321.
*
* Copyright: 2007-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2007, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
@@ -23,7 +23,7 @@
*
* @param ctx context to initialize
*/
void rhash_md5_init(md5_ctx *ctx)
void rhash_md5_init(md5_ctx* ctx)
{
ctx->length = 0;
@@ -162,7 +162,7 @@ static void rhash_md5_process_block(unsigned state[4], const unsigned* x)
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size)
void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
@@ -205,7 +205,7 @@ void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size)
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_md5_final(md5_ctx *ctx, unsigned char* result)
void rhash_md5_final(md5_ctx* ctx, unsigned char* result)
{
unsigned index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
@@ -213,8 +213,8 @@ void rhash_md5_final(md5_ctx *ctx, unsigned char* result)
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= ~(0xFFFFFFFF << shift);
ctx->message[index++] ^= 0x80 << shift;
ctx->message[index] &= ~(0xFFFFFFFFu << shift);
ctx->message[index++] ^= 0x80u << shift;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
+3 -3
View File
@@ -20,9 +20,9 @@ typedef struct md5_ctx
/* hash functions */
void rhash_md5_init(md5_ctx *ctx);
void rhash_md5_update(md5_ctx *ctx, const unsigned char* msg, size_t size);
void rhash_md5_final(md5_ctx *ctx, unsigned char result[16]);
void rhash_md5_init(md5_ctx* ctx);
void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_md5_final(md5_ctx* ctx, unsigned char result[16]);
#ifdef __cplusplus
} /* extern "C" */
+76 -248
View File
@@ -1,42 +1,40 @@
/* rhash.c - implementation of LibRHash library calls
*
* Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* modifier for Windows DLL */
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
# define RHASH_API __declspec(dllexport)
#endif
/* macros for large file support, must be defined before any include file */
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include <string.h> /* memset() */
#include <stdlib.h> /* free() */
#include <stddef.h> /* ptrdiff_t */
#include <stdio.h>
#include "rhash.h"
#include "algorithms.h"
#include "byte_order.h"
#include "hex.h"
#include "plug_openssl.h"
#include "torrent.h"
#include "util.h"
#include <assert.h>
#include <errno.h>
/* modifier for Windows DLL */
#if defined(_WIN32) && defined(RHASH_EXPORTS)
# define RHASH_API __declspec(dllexport)
#endif
#include "byte_order.h"
#include "algorithms.h"
#include "torrent.h"
#include "plug_openssl.h"
#include "util.h"
#include "hex.h"
#include "rhash.h" /* RHash library interface */
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#define STATE_ACTIVE 0xb01dbabe
#define STATE_STOPED 0xdeadbeef
@@ -45,11 +43,8 @@
#define RCTX_FINALIZED 0x2
#define RCTX_FINALIZED_MASK (RCTX_AUTO_FINAL | RCTX_FINALIZED)
#define RHPR_FORMAT (RHPR_RAW | RHPR_HEX | RHPR_BASE32 | RHPR_BASE64)
#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_REVERSE)
#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_URLENCODE | RHPR_REVERSE)
/**
* Initialize static data of rhash algorithms
*/
void rhash_library_init(void)
{
rhash_init_algorithms(RHASH_ALL_HASHES);
@@ -58,31 +53,18 @@ void rhash_library_init(void)
#endif
}
/**
* Returns the number of supported hash algorithms.
*
* @return the number of supported hash functions
*/
int RHASH_API rhash_count(void)
{
return rhash_info_size;
}
/* Lo-level rhash library functions */
/* LOW-LEVEL LIBRHASH INTERFACE */
/**
* Allocate and initialize RHash context for calculating hash(es).
* After initializing rhash_update()/rhash_final() functions should be used.
* Then the context must be freed by calling rhash_free().
*
* @param hash_id union of bit flags, containing ids of hashes to calculate.
* @return initialized rhash context, NULL on error and errno is set
*/
RHASH_API rhash rhash_init(unsigned hash_id)
{
unsigned tail_bit_index; /* index of hash_id trailing bit */
unsigned num = 0; /* number of hashes to compute */
rhash_context_ext *rctx = NULL; /* allocated rhash context */
rhash_context_ext* rctx = NULL; /* allocated rhash context */
size_t hash_size_sum = 0; /* size of hash contexts to store in rctx */
unsigned i, bit_index, id;
@@ -123,7 +105,7 @@ RHASH_API rhash rhash_init(unsigned hash_id)
}
/* align the size of the rhash context common part */
aligned_size = (offsetof(rhash_context_ext, vector[num]) + 7) & ~7;
aligned_size = ((offsetof(rhash_context_ext, vector) + sizeof(rhash_vector_item) * num) + 7) & ~7;
assert(aligned_size >= sizeof(rhash_context_ext));
/* allocate rhash context with enough memory to store contexts of all used hashes */
@@ -168,11 +150,6 @@ RHASH_API rhash rhash_init(unsigned hash_id)
return &rctx->rc; /* return allocated and initialized rhash context */
}
/**
* Free RHash context memory.
*
* @param ctx the context to free.
*/
void rhash_free(rhash ctx)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
@@ -193,12 +170,6 @@ void rhash_free(rhash ctx)
free(ectx);
}
/**
* Re-initialize RHash context to reuse it.
* Useful to speed up processing of many small messages.
*
* @param ctx context to reinitialize
*/
RHASH_API void rhash_reset(rhash ctx)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
@@ -221,15 +192,6 @@ RHASH_API void rhash_reset(rhash ctx)
ectx->flags &= ~RCTX_FINALIZED; /* clear finalized state */
}
/**
* Calculate hashes of message.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the rhash context
* @param message message chunk
* @param length length of the message chunk
* @return 0 on success; On fail return -1 and set errno
*/
RHASH_API int rhash_update(rhash ctx, const void* message, size_t length)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
@@ -249,13 +211,6 @@ RHASH_API int rhash_update(rhash ctx, const void* message, size_t length)
return 0; /* no error processing at the moment */
}
/**
* Finalize hash calculation and optionally store the first hash.
*
* @param ctx the rhash context
* @param first_result optional buffer to store a calculated hash with the lowest available id
* @return 0 on success; On fail return -1 and set errno
*/
RHASH_API int rhash_final(rhash ctx, unsigned char* first_result)
{
unsigned i = 0;
@@ -293,7 +248,7 @@ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
unsigned i;
rhash_vector_item *item;
rhash_vector_item* item;
struct rhash_hash_info* info;
unsigned char* digest;
@@ -330,34 +285,14 @@ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result)
}
}
/**
* Set the callback function to be called from the
* rhash_file() and rhash_file_update() functions
* on processing every file block. The file block
* size is set internally by rhash and now is 8 KiB.
*
* @param ctx rhash context
* @param callback pointer to the callback function
* @param callback_data pointer to data passed to the callback
*/
RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data)
{
((rhash_context_ext*)ctx)->callback = callback;
((rhash_context_ext*)ctx)->callback = (void*)callback;
((rhash_context_ext*)ctx)->callback_data = callback_data;
}
/* HIGH-LEVEL LIBRHASH INTERFACE */
/* hi-level message hashing interface */
/**
* Compute a hash of the given message.
*
* @param hash_id id of hash sum to compute
* @param message the message to process
* @param length message length
* @param result buffer to receive binary hash string
* @return 0 on success, -1 on error
*/
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result)
{
rhash ctx;
@@ -370,22 +305,12 @@ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, un
return 0;
}
/**
* Hash a file or stream. Multiple hashes can be computed.
* First, inintialize ctx parameter with rhash_init() before calling
* rhash_file_update(). Then use rhash_final() and rhash_print()
* to retrive hash values. Finaly call rhash_free() on ctx
* to free allocated memory or call rhash_reset() to reuse ctx.
*
* @param ctx rhash context
* @param fd descriptor of the file to hash
* @return 0 on success, -1 on error and errno is set
*/
RHASH_API int rhash_file_update(rhash ctx, FILE* fd)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
const size_t block_size = 8192;
unsigned char *buffer, *pmem;
unsigned char* buffer;
unsigned char* pmem;
size_t length = 0, align8;
int res = 0;
if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
@@ -423,14 +348,6 @@ RHASH_API int rhash_file_update(rhash ctx, FILE* fd)
return res;
}
/**
* Compute a single hash for given file.
*
* @param hash_id id of hash sum to compute
* @param filepath path to the file to hash
* @param result buffer to receive hash value with the lowest requested id
* @return 0 on success, -1 on error and errno is set
*/
RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result)
{
FILE* fd;
@@ -445,7 +362,10 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char*
if ((fd = fopen(filepath, "rb")) == NULL) return -1;
if ((ctx = rhash_init(hash_id)) == NULL) return -1;
if ((ctx = rhash_init(hash_id)) == NULL) {
fclose(fd);
return -1;
}
res = rhash_file_update(ctx, fd); /* hash the file */
fclose(fd);
@@ -458,14 +378,6 @@ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char*
#ifdef _WIN32 /* windows only function */
#include <share.h>
/**
* Compute a single hash for given file.
*
* @param hash_id id of hash sum to compute
* @param filepath path to the file to hash
* @param result buffer to receive hash value with the lowest requested id
* @return 0 on success, -1 on error, -1 on error and errno is set
*/
RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result)
{
FILE* fd;
@@ -480,7 +392,10 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch
if ((fd = _wfsopen(filepath, L"rb", _SH_DENYWR)) == NULL) return -1;
if ((ctx = rhash_init(hash_id)) == NULL) return -1;
if ((ctx = rhash_init(hash_id)) == NULL) {
fclose(fd);
return -1;
}
res = rhash_file_update(ctx, fd); /* hash the file */
fclose(fd);
@@ -493,39 +408,12 @@ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned ch
/* RHash information functions */
/**
* Returns information about a hash function by its hash_id.
*
* @param hash_id the id of hash algorithm
* @return pointer to the rhash_info structure containing the information
*/
const rhash_info* rhash_info_by_id(unsigned hash_id)
{
hash_id &= RHASH_ALL_HASHES;
/* check that only one bit is set */
if (hash_id != (hash_id & -(int)hash_id)) return NULL;
/* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */
return rhash_info_table[rhash_ctz(hash_id)].info;
}
/**
* Detect default digest output format for given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return 1 for base32 format, 0 for hexadecimal
*/
RHASH_API int rhash_is_base32(unsigned hash_id)
{
/* fast method is just to test a bit-mask */
return ((hash_id & (RHASH_TTH | RHASH_AICH)) != 0);
}
/**
* Returns size of binary digest for given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return digest size in bytes
*/
RHASH_API int rhash_get_digest_size(unsigned hash_id)
{
hash_id &= RHASH_ALL_HASHES;
@@ -533,12 +421,6 @@ RHASH_API int rhash_get_digest_size(unsigned hash_id)
return (int)rhash_info_table[rhash_ctz(hash_id)].info->digest_size;
}
/**
* Returns length of digest hash string in default output format.
*
* @param hash_id the id of hash algorithm
* @return the length of hash string
*/
RHASH_API int rhash_get_hash_length(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
@@ -546,26 +428,12 @@ RHASH_API int rhash_get_hash_length(unsigned hash_id)
BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0);
}
/**
* Returns a name of given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return algorithm name
*/
RHASH_API const char* rhash_get_name(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
return (info ? info->name : 0);
}
/**
* Returns a name part of magnet urn of the given hash algorithm.
* Such magnet_name is used to generate a magnet link of the form
* urn:&lt;magnet_name&gt;=&lt;hash_value&gt;.
*
* @param hash_id the id of hash algorithm
* @return name
*/
RHASH_API const char* rhash_get_magnet_name(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
@@ -594,7 +462,7 @@ static size_t rhash_get_magnet_url_size(const char* filepath,
}
if (filepath) {
size += 4 + rhash_urlencode(NULL, filepath);
size += 4 + rhash_urlencode(NULL, filepath, strlen(filepath), 0);
}
/* loop through hash values */
@@ -605,34 +473,20 @@ static size_t rhash_get_magnet_url_size(const char* filepath,
size += (7 + 2) + strlen(name);
size += rhash_print(NULL, context, bit,
(bit & (RHASH_SHA1 | RHASH_BTIH) ? RHPR_BASE32 : 0));
(bit & RHASH_SHA1 ? RHPR_BASE32 : 0));
}
return size;
}
/**
* Print magnet link with given filepath and calculated hash sums into the
* output buffer. The hash_mask can limit which hash values will be printed.
* The function returns the size of the required buffer.
* If output is NULL the .
*
* @param output a string buffer to receive the magnet link or NULL
* @param filepath the file path to be printed or NULL
* @param context algorithms state
* @param hash_mask bit mask of the hash sums to add to the link
* @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
* RHPR_FILESIZE
* @return number of written characters, including terminating '\0' on success, 0 on fail
*/
RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
rhash context, unsigned hash_mask, int flags)
{
int i;
const char* begin = output;
if (output == NULL) return rhash_get_magnet_url_size(
filepath, context, hash_mask, flags);
if (output == NULL)
return rhash_get_magnet_url_size(filepath, context, hash_mask, flags);
/* RHPR_NO_MAGNET, RHPR_FILESIZE */
if ((flags & RHPR_NO_MAGNET) == 0) {
@@ -647,13 +501,13 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
*(output++) = '&';
}
flags &= RHPR_UPPERCASE;
if (filepath) {
strcpy(output, "dn=");
output += 3;
output += rhash_urlencode(output, filepath);
output += rhash_urlencode(output, filepath, strlen(filepath), flags);
*(output++) = '&';
}
flags &= RHPR_UPPERCASE;
for (i = 0; i < 2; i++) {
unsigned bit;
@@ -674,7 +528,7 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
output += strlen(name);
*(output++) = ':';
output += rhash_print(output, context, bit,
(bit & (RHASH_SHA1 | RHASH_BTIH) ? flags | RHPR_BASE32 : flags));
(bit & RHASH_SHA1 ? flags | RHPR_BASE32 : flags));
*(output++) = '&';
}
}
@@ -683,62 +537,39 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
return (output - begin);
}
/* hash sum output */
/**
* Print a text presentation of a given hash sum to the specified buffer,
*
* @param output a buffer to print the hash to
* @param bytes a hash sum to print
* @param size a size of hash sum in bytes
* @param flags a bit-mask controlling how to format the hash sum,
* can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
* RHPR_BASE64, RHPR_UPPERCASE, RHPR_REVERSE
* @return the number of written characters
*/
size_t rhash_print_bytes(char* output, const unsigned char* bytes,
size_t size, int flags)
/* HASH SUM OUTPUT INTERFACE */
size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags)
{
size_t str_len;
size_t result_length;
int upper_case = (flags & RHPR_UPPERCASE);
int format = (flags & ~RHPR_MODIFIER);
switch (format) {
case RHPR_HEX:
str_len = size * 2;
rhash_byte_to_hex(output, bytes, (unsigned)size, upper_case);
result_length = size * 2;
rhash_byte_to_hex(output, bytes, size, upper_case);
break;
case RHPR_BASE32:
str_len = BASE32_LENGTH(size);
rhash_byte_to_base32(output, bytes, (unsigned)size, upper_case);
result_length = BASE32_LENGTH(size);
rhash_byte_to_base32(output, bytes, size, upper_case);
break;
case RHPR_BASE64:
str_len = BASE64_LENGTH(size);
rhash_byte_to_base64(output, bytes, (unsigned)size);
result_length = rhash_base64_url_encoded_helper(output, bytes, size, (flags & RHPR_URLENCODE), upper_case);
break;
default:
str_len = size;
memcpy(output, bytes, size);
if (flags & RHPR_URLENCODE) {
result_length = rhash_urlencode(output, (char*)bytes, size, upper_case);
} else {
memcpy(output, bytes, size);
result_length = size;
}
break;
}
return str_len;
return result_length;
}
/**
* Print text presentation of a hash sum with given hash_id to the specified
* output buffer. If the hash_id is zero, then print the hash sum with
* the lowest id stored in the hash context.
* The function call fails if the context doesn't include a hash with the
* given hash_id.
*
* @param output a buffer to print the hash to
* @param context algorithms state
* @param hash_id id of the hash sum to print or 0 to print the first hash
* saved in the context.
* @param flags a bitmask controlling how to print the hash. Can contain flags
* RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
* @return the number of written characters on success or 0 on fail
*/
size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int flags)
{
const rhash_info* info;
@@ -759,15 +590,16 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int
}
if (output == NULL) {
size_t multiplier = (flags & RHPR_URLENCODE ? 3 : 1);
switch (flags & RHPR_FORMAT) {
case RHPR_HEX:
return (digest_size * 2);
case RHPR_BASE32:
return BASE32_LENGTH(digest_size);
case RHPR_BASE64:
return BASE64_LENGTH(digest_size);
return BASE64_LENGTH(digest_size) * multiplier;
default:
return digest_size;
return digest_size * multiplier;
}
}
@@ -776,7 +608,8 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int
if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) {
/* reverse the digest */
unsigned char *p = digest, *r = digest + digest_size - 1;
unsigned char* p = digest;
unsigned char* r = digest + digest_size - 1;
char tmp;
for (; p < r; p++, r--) {
tmp = *p;
@@ -788,7 +621,7 @@ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int
return rhash_print_bytes(output, digest, digest_size, flags);
}
#if defined(_WIN32) && defined(RHASH_EXPORTS)
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved);
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
@@ -850,17 +683,8 @@ static rhash_uptr_t process_bt_msg(unsigned msg_id, torrent_ctx* bt, rhash_uptr_
return 0;
}
#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
#define PVOID2UPTR(p) ((rhash_uptr_t)(((char*)(p)) + 0))
/**
* Process a rhash message.
*
* @param msg_id message identifier
* @param dst message destination (can be NULL for generic messages)
* @param ldata data depending on message
* @param rdata data depending on message
* @return message-specific data
*/
RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata)
{
/* for messages working with rhash context */
@@ -901,6 +725,10 @@ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t l
case RMSG_GET_OPENSSL_MASK:
return rhash_openssl_hash_mask;
#endif
case RMSG_GET_OPENSSL_SUPPORTED_MASK:
return rhash_get_openssl_supported_hash_mask();
case RMSG_GET_OPENSSL_AVAILABLE_MASK:
return rhash_get_openssl_available_hash_mask();
/* BitTorrent related messages */
case RMSG_BT_ADD_FILE:
+320 -83
View File
@@ -9,7 +9,9 @@ extern "C" {
#endif
#ifndef RHASH_API
/* modifier for LibRHash functions */
/**
* Modifier for LibRHash functions
*/
# define RHASH_API
#endif
@@ -31,11 +33,11 @@ enum rhash_ids
RHASH_AICH = 0x100,
RHASH_WHIRLPOOL = 0x200,
RHASH_RIPEMD160 = 0x400,
RHASH_GOST = 0x800,
RHASH_GOST_CRYPTOPRO = 0x1000,
RHASH_HAS160 = 0x2000,
RHASH_SNEFRU128 = 0x4000,
RHASH_SNEFRU256 = 0x8000,
RHASH_GOST94 = 0x800,
RHASH_GOST94_CRYPTOPRO = 0x1000,
RHASH_HAS160 = 0x2000,
RHASH_GOST12_256 = 0x4000,
RHASH_GOST12_512 = 0x8000,
RHASH_SHA224 = 0x10000,
RHASH_SHA256 = 0x20000,
RHASH_SHA384 = 0x40000,
@@ -46,30 +48,42 @@ enum rhash_ids
RHASH_SHA3_256 = 0x0800000,
RHASH_SHA3_384 = 0x1000000,
RHASH_SHA3_512 = 0x2000000,
RHASH_CRC32C = 0x4000000,
RHASH_SNEFRU128 = 0x8000000,
RHASH_SNEFRU256 = 0x10000000,
/** The bit-mask containing all supported hashe functions */
RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 |
RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO |
/**
* The bit-mask containing all supported hashe functions.
*/
RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |
RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH |
RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 |
RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |
RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |
RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |
RHASH_EDONR256 | RHASH_EDONR512,
/** The number of supported hash functions */
RHASH_HASH_COUNT = 26
RHASH_GOST = RHASH_GOST94, /* deprecated constant name */
RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO, /* deprecated constant name */
/**
* The number of supported hash functions.
*/
RHASH_HASH_COUNT = 29
};
/**
* The rhash context structure contains contexts for several hash functions
* The rhash context structure contains contexts for several hash functions.
*/
typedef struct rhash_context
{
/** The size of the hashed message */
/**
* The size of the hashed message.
*/
unsigned long long msg_size;
/**
* The bit-mask containing identifiers of the hashes being calculated
* The bit-mask containing identifiers of the hashes being calculated.
*/
unsigned hash_id;
} rhash_context;
@@ -82,107 +96,283 @@ typedef struct rhash_context
typedef struct rhash_context* rhash;
#endif /* LIBRHASH_RHASH_CTX_DEFINED */
/** type of a callback to be called periodically while hashing a file */
/**
* Type of a callback to be called periodically while hashing a file.
*/
typedef void (*rhash_callback_t)(void* data, unsigned long long offset);
RHASH_API void rhash_library_init(void); /* initialize static data */
/**
* Initialize static data of rhash algorithms
*/
RHASH_API void rhash_library_init(void);
/* hi-level hashing functions */
/* HIGH-LEVEL LIBRHASH INTERFACE */
/**
* Compute a hash of the given message.
*
* @param hash_id id of hash sum to compute
* @param message the message to process
* @param length message length
* @param result buffer to receive binary hash string
* @return 0 on success, -1 on error
*/
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);
RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
#ifdef _WIN32 /* windows only function */
/**
* Compute a single hash for given file.
*
* @param hash_id id of hash sum to compute
* @param filepath path to the file to hash
* @param result buffer to receive hash value with the lowest requested id
* @return 0 on success, -1 on error and errno is set
*/
RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
#ifdef _WIN32
/**
* Compute a single hash for given file (Windows-specific function).
*
* @param hash_id id of hash sum to compute
* @param filepath path to the file to hash
* @param result buffer to receive hash value with the lowest requested id
* @return 0 on success, -1 on error, -1 on error and errno is set
*/
RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);
#endif
/* lo-level interface */
/* LOW-LEVEL LIBRHASH INTERFACE */
/**
* Allocate and initialize RHash context for calculating hash(es).
* After initializing rhash_update()/rhash_final() functions should be used.
* Then the context must be freed by calling rhash_free().
*
* @param hash_id union of bit flags, containing ids of hashes to calculate.
* @return initialized rhash context, NULL on error and errno is set
*/
RHASH_API rhash rhash_init(unsigned hash_id);
/*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/
RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);
RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);
RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */
/**
* Calculate hashes of message.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the rhash context
* @param message message chunk
* @param length length of the message chunk
* @return 0 on success; On fail return -1 and set errno
*/
RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);
/**
* Hash a file or stream. Multiple hashes can be computed.
* First, inintialize ctx parameter with rhash_init() before calling
* rhash_file_update(). Then use rhash_final() and rhash_print()
* to retrive hash values. Finaly call rhash_free() on ctx
* to free allocated memory or call rhash_reset() to reuse ctx.
*
* @param ctx rhash context
* @param fd descriptor of the file to hash
* @return 0 on success, -1 on error and errno is set
*/
RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
/**
* Finalize hash calculation and optionally store the first hash.
*
* @param ctx the rhash context
* @param first_result optional buffer to store a calculated hash with the lowest available id
* @return 0 on success; On fail return -1 and set errno
*/
RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);
/**
* Re-initialize RHash context to reuse it.
* Useful to speed up processing of many small messages.
*
* @param ctx context to reinitialize
*/
RHASH_API void rhash_reset(rhash ctx);
/**
* Free RHash context memory.
*
* @param ctx the context to free.
*/
RHASH_API void rhash_free(rhash ctx);
/* additional lo-level functions */
/**
* Set the callback function to be called from the
* rhash_file() and rhash_file_update() functions
* on processing every file block. The file block
* size is set internally by rhash and now is 8 KiB.
*
* @param ctx rhash context
* @param callback pointer to the callback function
* @param callback_data pointer to data passed to the callback
*/
RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
/** bit-flag: default hash output format is base32 */
#define RHASH_INFO_BASE32 1
/* INFORMATION FUNCTIONS */
/**
* Information about a hash function.
* Returns the number of supported hash algorithms.
*
* @return the number of supported hash functions
*/
typedef struct rhash_info
{
/** hash function indentifier */
unsigned hash_id;
/** flags bit-mask, including RHASH_INFO_BASE32 bit */
unsigned flags;
/** size of binary message digest in bytes */
size_t digest_size;
const char* name;
const char* magnet_name;
} rhash_info;
/* information functions */
RHASH_API int rhash_count(void); /* number of supported hashes */
/**
* Returns size of binary digest for given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return digest size in bytes
*/
RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */
/**
* Returns length of digest hash string in default output format.
*
* @param hash_id the id of hash algorithm
* @return the length of hash string
*/
RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */
/**
* Detect default digest output format for given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return 1 for base32 format, 0 for hexadecimal
*/
RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */
/**
* Returns a name of given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return algorithm name
*/
RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */
/**
* Returns a name part of magnet urn of the given hash algorithm.
* Such magnet_name is used to generate a magnet link of the form
* urn:&lt;magnet_name&gt;=&lt;hash_value&gt;.
*
* @param hash_id the id of hash algorithm
* @return name
*/
RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */
/* note, that rhash_info_by_id() is not exported to a shared library or DLL */
const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
/* HASH SUM OUTPUT INTERFACE */
/**
* Flags for printing a hash sum
* Flags for printing a hash sum.
*/
enum rhash_print_sum_flags
{
/** print in a default format */
/*
* Print in a default format
*/
RHPR_DEFAULT = 0x0,
/** output as binary message digest */
/*
* Output as binary message digest
*/
RHPR_RAW = 0x1,
/** print as a hexadecimal string */
/*
* Print as a hexadecimal string
*/
RHPR_HEX = 0x2,
/** print as a base32-encoded string */
/*
* Print as a base32-encoded string
*/
RHPR_BASE32 = 0x3,
/** print as a base64-encoded string */
/*
* Print as a base64-encoded string
*/
RHPR_BASE64 = 0x4,
/**
/*
* Print as an uppercase string. Can be used
* for base32 or hexadecimal format only.
*/
RHPR_UPPERCASE = 0x8,
/**
/*
* Reverse hash bytes. Can be used for GOST hash.
*/
RHPR_REVERSE = 0x10,
/** don't print 'magnet:?' prefix in rhash_print_magnet */
/*
* Don't print 'magnet:?' prefix in rhash_print_magnet
*/
RHPR_NO_MAGNET = 0x20,
/** print file size in rhash_print_magnet */
/*
* Print file size in rhash_print_magnet
*/
RHPR_FILESIZE = 0x40,
/*
* Print as URL-encoded string
*/
RHPR_URLENCODE = 0x80
};
/* output hash into the given buffer */
/**
* Print a text presentation of a given hash sum to the specified buffer.
*
* @param output a buffer to print the hash to
* @param bytes a hash sum to print
* @param size a size of hash sum in bytes
* @param flags a bit-mask controlling how to format the hash sum,
* can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
* RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE
* @return the number of written characters
*/
RHASH_API size_t rhash_print_bytes(char* output,
const unsigned char* bytes, size_t size, int flags);
/**
* Print text presentation of a hash sum with given hash_id to the specified
* output buffer. If the hash_id is zero, then print the hash sum with
* the lowest id stored in the hash context.
* The function call fails if the context doesn't include a hash with the
* given hash_id.
*
* @param output a buffer to print the hash to
* @param context algorithms state
* @param hash_id id of the hash sum to print or 0 to print the first hash
* saved in the context.
* @param flags a bitmask controlling how to print the hash. Can contain flags
* RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
* @return the number of written characters on success or 0 on fail
*/
RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id,
int flags);
/* output magnet URL into the given buffer */
/**
* Print magnet link with given filepath and calculated hash sums into the
* output buffer. The hash_mask can limit which hash values will be printed.
* The function returns the size of the required buffer.
* If output is NULL the .
*
* @param output a string buffer to receive the magnet link or NULL
* @param filepath the file path to be printed or NULL
* @param context algorithms state
* @param hash_mask bit mask of the hash sums to add to the link
* @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
* RHPR_FILESIZE
* @return number of written characters, including terminating '\0' on success, 0 on fail
*/
RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
rhash context, unsigned hash_mask, int flags);
/* macros for message API */
/** The type of an unsigned integer large enough to hold a pointer */
/* MESSAGE API */
/**
* The type of an unsigned integer large enough to hold a pointer.
*/
#if defined(UINTPTR_MAX)
typedef uintptr_t rhash_uptr_t;
#elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
@@ -192,14 +382,28 @@ typedef unsigned long long rhash_uptr_t;
typedef unsigned long rhash_uptr_t;
#endif
/** The value returned by rhash_transmit on error */
/**
* The value returned by rhash_transmit on error.
*/
#define RHASH_ERROR ((rhash_uptr_t)-1)
/** Convert a pointer to rhash_uptr_t */
/**
* Convert a pointer to rhash_uptr_t.
*/
#define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str))
/** Convert a rhash_uptr_t to a void* pointer */
#define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u)))
/**
* Convert a rhash_uptr_t to a void* pointer.
*/
#define RHASH_UPTR2PVOID(u) ((void*)((u) + 0))
/* rhash API to set/get data via messages */
/**
* Process a rhash message.
*
* @param msg_id message identifier
* @param dst message destination (can be NULL for generic messages)
* @param ldata data depending on message
* @param rdata data depending on message
* @return message-specific data
*/
RHASH_API rhash_uptr_t rhash_transmit(
unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata);
@@ -212,6 +416,8 @@ RHASH_API rhash_uptr_t rhash_transmit(
#define RMSG_SET_AUTOFINAL 5
#define RMSG_SET_OPENSSL_MASK 10
#define RMSG_GET_OPENSSL_MASK 11
#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12
#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13
#define RMSG_BT_ADD_FILE 32
#define RMSG_BT_SET_OPTIONS 33
@@ -221,25 +427,39 @@ RHASH_API rhash_uptr_t rhash_transmit(
#define RMSG_BT_GET_TEXT 37
#define RMSG_BT_SET_BATCH_SIZE 38
/* possible BitTorrent options for the RMSG_BT_SET_OPTIONS message */
/**
* RMSG_BT_SET_OPTIONS message option: generate private BitTorrent.
*/
#define RHASH_BT_OPT_PRIVATE 1
/**
* RMSG_BT_SET_OPTIONS message option: calculate infohash without torrent file body.
*/
#define RHASH_BT_OPT_INFOHASH_ONLY 2
/* helper macros */
/** Get a pointer to context of the specified hash function */
/* HELPER MACROS */
/**
* Get a pointer to context of the specified hash function.
*/
#define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0))
/** Cancel hash calculation of a file */
/**
* Cancel hash calculation of a file.
*/
#define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0)
/** Return non-zero if hash calculation was canceled, zero otherwise */
/**
* Return non-zero if hash calculation was canceled, zero otherwise.
*/
#define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0)
/** Return non-zero if rhash_final was called for rhash_context */
/**
* Return non-zero if rhash_final was called for rhash_context.
*/
#define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0)
/**
* Turn on/off the auto-final flag for the given rhash_context. By default
* auto-final is on, which means rhash_final is called automatically, if
* needed when a hash value is retrived by rhash_print call.
* needed when a hash value is retrieved by rhash_print call.
*/
#define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0)
@@ -252,19 +472,36 @@ RHASH_API rhash_uptr_t rhash_transmit(
#define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0)
/**
* Return current bit-mask of hash algorithms selected to be calculated
* by OpenSSL library.
* Return current bit-mask of hash algorithms selected to be calculated by OpenSSL
* library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support.
*/
#define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0)
/** The bit mask of hash algorithms implemented by OpenSSL */
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
# define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \
RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \
RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL)
#else
# define RHASH_OPENSSL_SUPPORTED_HASHES 0
#endif
/**
* Return the bit-mask of algorithms that can be provided by the OpenSSL plugin,
* if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is
* a constant value computed at compile-time.
*/
#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0)
/**
* Return the bit-mask of algorithms that are successfully loaded from
* OpenSSL library. If the library is not loaded or not supported by LibRHash,
* then return 0.
*/
#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0)
/**
* Return non-zero if LibRHash hash been compiled with OpenSSL support,
* and zero otherwise.
*/
#define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR)
/**
* Legacy macro. The bit mask of hash algorithms implemented by OpenSSL.
*/
# define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask())
#ifdef __cplusplus
} /* extern "C" */
+13 -13
View File
@@ -1,18 +1,18 @@
/* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
* based on RFC 3174.
*
* Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
@@ -24,7 +24,7 @@
*
* @param ctx context to initialize
*/
void rhash_sha1_init(sha1_ctx *ctx)
void rhash_sha1_init(sha1_ctx* ctx)
{
ctx->length = 0;
@@ -121,7 +121,7 @@ static void rhash_sha1_process_block(unsigned* hash, const unsigned* block)
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size)
void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
@@ -164,7 +164,7 @@ void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size)
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result)
void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result)
{
unsigned index = (unsigned)ctx->length & 63;
unsigned* msg32 = (unsigned*)ctx->message;
+3 -3
View File
@@ -20,9 +20,9 @@ typedef struct sha1_ctx
/* hash functions */
void rhash_sha1_init(sha1_ctx *ctx);
void rhash_sha1_update(sha1_ctx *ctx, const unsigned char* msg, size_t size);
void rhash_sha1_final(sha1_ctx *ctx, unsigned char* result);
void rhash_sha1_init(sha1_ctx* ctx);
void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
+17 -17
View File
@@ -1,18 +1,18 @@
/* sha256.c - an implementation of SHA-256/224 hash functions
* based on FIPS 180-3 (Federal Information Processing Standart).
*
* Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
@@ -65,7 +65,7 @@ static const unsigned rhash_k256[64] = {
*
* @param ctx context to initialize
*/
void rhash_sha256_init(sha256_ctx *ctx)
void rhash_sha256_init(sha256_ctx* ctx)
{
/* Initial values. These words were obtained by taking the first 32
* bits of the fractional parts of the square roots of the first
@@ -87,7 +87,7 @@ void rhash_sha256_init(sha256_ctx *ctx)
*
* @param ctx context to initialize
*/
void rhash_sha224_init(struct sha256_ctx *ctx)
void rhash_sha224_init(struct sha256_ctx* ctx)
{
/* Initial values from FIPS 180-3. These words were obtained by taking
* bits from 33th to 64th of the fractional parts of the square
@@ -113,7 +113,7 @@ static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16])
{
unsigned A, B, C, D, E, F, G, H;
unsigned W[16];
const unsigned *k;
const unsigned* k;
int i;
A = hash[0], B = hash[1], C = hash[2], D = hash[3];
@@ -168,7 +168,7 @@ static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16])
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size)
void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 63;
ctx->length += size;
@@ -210,7 +210,7 @@ void rhash_sha256_update(sha256_ctx *ctx, const unsigned char *msg, size_t size)
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result)
void rhash_sha256_final(sha256_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
@@ -218,8 +218,8 @@ void rhash_sha256_final(sha256_ctx *ctx, unsigned char* result)
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= le2me_32(~(0xFFFFFFFF << shift));
ctx->message[index++] ^= le2me_32(0x80 << shift);
ctx->message[index] &= le2me_32(~(0xFFFFFFFFu << shift));
ctx->message[index++] ^= le2me_32(0x80u << shift);
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
+4 -4
View File
@@ -20,10 +20,10 @@ typedef struct sha256_ctx
unsigned digest_length; /* length of the algorithm digest in bytes */
} sha256_ctx;
void rhash_sha224_init(sha256_ctx *ctx);
void rhash_sha256_init(sha256_ctx *ctx);
void rhash_sha256_update(sha256_ctx *ctx, const unsigned char* data, size_t length);
void rhash_sha256_final(sha256_ctx *ctx, unsigned char result[32]);
void rhash_sha224_init(sha256_ctx* ctx);
void rhash_sha256_init(sha256_ctx* ctx);
void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* data, size_t length);
void rhash_sha256_final(sha256_ctx* ctx, unsigned char result[32]);
#ifdef __cplusplus
} /* extern "C" */
+57 -51
View File
@@ -3,18 +3,18 @@
* The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
* by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
*
* Copyright: 2013 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2013, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
@@ -36,7 +36,7 @@ static uint64_t keccak_round_constants[NumberOfRounds] = {
};
/* Initializing a sha3 context for given number of output bits */
static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits)
static void rhash_keccak_init(sha3_ctx* ctx, unsigned bits)
{
/* NB: The Keccak capacity parameter = bits * 2 */
unsigned rate = 1600 - bits * 2;
@@ -51,7 +51,7 @@ static void rhash_keccak_init(sha3_ctx *ctx, unsigned bits)
*
* @param ctx context to initialize
*/
void rhash_sha3_224_init(sha3_ctx *ctx)
void rhash_sha3_224_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 224);
}
@@ -61,7 +61,7 @@ void rhash_sha3_224_init(sha3_ctx *ctx)
*
* @param ctx context to initialize
*/
void rhash_sha3_256_init(sha3_ctx *ctx)
void rhash_sha3_256_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 256);
}
@@ -71,7 +71,7 @@ void rhash_sha3_256_init(sha3_ctx *ctx)
*
* @param ctx context to initialize
*/
void rhash_sha3_384_init(sha3_ctx *ctx)
void rhash_sha3_384_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 384);
}
@@ -81,37 +81,37 @@ void rhash_sha3_384_init(sha3_ctx *ctx)
*
* @param ctx context to initialize
*/
void rhash_sha3_512_init(sha3_ctx *ctx)
void rhash_sha3_512_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 512);
}
#define XORED_A(i) A[(i)] ^ A[(i) + 5] ^ A[(i) + 10] ^ A[(i) + 15] ^ A[(i) + 20]
#define THETA_STEP(i) \
A[(i)] ^= D[(i)]; \
A[(i) + 5] ^= D[(i)]; \
A[(i) + 10] ^= D[(i)]; \
A[(i) + 15] ^= D[(i)]; \
A[(i) + 20] ^= D[(i)] \
/* Keccak theta() transformation */
static void keccak_theta(uint64_t *A)
static void keccak_theta(uint64_t* A)
{
unsigned int x;
uint64_t C[5], D[5];
for (x = 0; x < 5; x++) {
C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20];
}
D[0] = ROTL64(C[1], 1) ^ C[4];
D[1] = ROTL64(C[2], 1) ^ C[0];
D[2] = ROTL64(C[3], 1) ^ C[1];
D[3] = ROTL64(C[4], 1) ^ C[2];
D[4] = ROTL64(C[0], 1) ^ C[3];
for (x = 0; x < 5; x++) {
A[x] ^= D[x];
A[x + 5] ^= D[x];
A[x + 10] ^= D[x];
A[x + 15] ^= D[x];
A[x + 20] ^= D[x];
}
uint64_t D[5];
D[0] = ROTL64(XORED_A(1), 1) ^ XORED_A(4);
D[1] = ROTL64(XORED_A(2), 1) ^ XORED_A(0);
D[2] = ROTL64(XORED_A(3), 1) ^ XORED_A(1);
D[3] = ROTL64(XORED_A(4), 1) ^ XORED_A(2);
D[4] = ROTL64(XORED_A(0), 1) ^ XORED_A(3);
THETA_STEP(0);
THETA_STEP(1);
THETA_STEP(2);
THETA_STEP(3);
THETA_STEP(4);
}
/* Keccak pi() transformation */
static void keccak_pi(uint64_t *A)
static void keccak_pi(uint64_t* A)
{
uint64_t A1;
A1 = A[1];
@@ -142,21 +142,27 @@ static void keccak_pi(uint64_t *A)
/* note: A[ 0] is left as is */
}
#define CHI_STEP(i) \
A0 = A[0 + (i)]; \
A1 = A[1 + (i)]; \
A[0 + (i)] ^= ~A1 & A[2 + (i)]; \
A[1 + (i)] ^= ~A[2 + (i)] & A[3 + (i)]; \
A[2 + (i)] ^= ~A[3 + (i)] & A[4 + (i)]; \
A[3 + (i)] ^= ~A[4 + (i)] & A0; \
A[4 + (i)] ^= ~A0 & A1 \
/* Keccak chi() transformation */
static void keccak_chi(uint64_t *A)
static void keccak_chi(uint64_t* A)
{
int i;
for (i = 0; i < 25; i += 5) {
uint64_t A0 = A[0 + i], A1 = A[1 + i];
A[0 + i] ^= ~A1 & A[2 + i];
A[1 + i] ^= ~A[2 + i] & A[3 + i];
A[2 + i] ^= ~A[3 + i] & A[4 + i];
A[3 + i] ^= ~A[4 + i] & A0;
A[4 + i] ^= ~A0 & A1;
}
uint64_t A0, A1;
CHI_STEP(0);
CHI_STEP(5);
CHI_STEP(10);
CHI_STEP(15);
CHI_STEP(20);
}
static void rhash_sha3_permutation(uint64_t *state)
static void rhash_sha3_permutation(uint64_t* state)
{
int round;
for (round = 0; round < NumberOfRounds; round++)
@@ -204,7 +210,7 @@ static void rhash_sha3_permutation(uint64_t *state)
* @param block the message block to process
* @param block_size the size of the processed block in bytes
*/
static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, size_t block_size)
static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t* block, size_t block_size)
{
/* expanded loop */
hash[ 0] ^= le2me_64(block[ 0]);
@@ -260,7 +266,7 @@ static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t *block, s
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size)
void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->rest;
size_t block_size = (size_t)ctx->block_size;
@@ -305,7 +311,7 @@ void rhash_sha3_update(sha3_ctx *ctx, const unsigned char *msg, size_t size)
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result)
void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result)
{
size_t digest_length = 100 - ctx->block_size / 2;
const size_t block_size = ctx->block_size;
@@ -333,7 +339,7 @@ void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result)
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result)
void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result)
{
size_t digest_length = 100 - ctx->block_size / 2;
const size_t block_size = ctx->block_size;
+7 -7
View File
@@ -31,12 +31,12 @@ typedef struct sha3_ctx
/* methods for calculating the hash function */
void rhash_sha3_224_init(sha3_ctx *ctx);
void rhash_sha3_256_init(sha3_ctx *ctx);
void rhash_sha3_384_init(sha3_ctx *ctx);
void rhash_sha3_512_init(sha3_ctx *ctx);
void rhash_sha3_update(sha3_ctx *ctx, const unsigned char* msg, size_t size);
void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result);
void rhash_sha3_224_init(sha3_ctx* ctx);
void rhash_sha3_256_init(sha3_ctx* ctx);
void rhash_sha3_384_init(sha3_ctx* ctx);
void rhash_sha3_512_init(sha3_ctx* ctx);
void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result);
#ifdef USE_KECCAK
#define rhash_keccak_224_init rhash_sha3_224_init
@@ -44,7 +44,7 @@ void rhash_sha3_final(sha3_ctx *ctx, unsigned char* result);
#define rhash_keccak_384_init rhash_sha3_384_init
#define rhash_keccak_512_init rhash_sha3_512_init
#define rhash_keccak_update rhash_sha3_update
void rhash_keccak_final(sha3_ctx *ctx, unsigned char* result);
void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result);
#endif
#ifdef __cplusplus
+15 -15
View File
@@ -1,18 +1,18 @@
/* sha512.c - an implementation of SHA-384/512 hash functions
* based on FIPS 180-3 (Federal Information Processing Standart).
*
* Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin@gmail.com>
* Copyright (c) 2010, Aleksey Kravchenko <rhash.admin@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so.
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk!
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include <string.h>
@@ -81,7 +81,7 @@ static const uint64_t rhash_k512[80] = {
*
* @param ctx context to initialize
*/
void rhash_sha512_init(sha512_ctx *ctx)
void rhash_sha512_init(sha512_ctx* ctx)
{
/* Initial values. These words were obtained by taking the first 32
* bits of the fractional parts of the square roots of the first
@@ -104,7 +104,7 @@ void rhash_sha512_init(sha512_ctx *ctx)
*
* @param ctx context to initialize
*/
void rhash_sha384_init(struct sha512_ctx *ctx)
void rhash_sha384_init(struct sha512_ctx* ctx)
{
/* Initial values from FIPS 180-3. These words were obtained by taking
* the first sixty-four bits of the fractional parts of the square
@@ -131,7 +131,7 @@ static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16])
{
uint64_t A, B, C, D, E, F, G, H;
uint64_t W[16];
const uint64_t *k;
const uint64_t* k;
int i;
A = hash[0], B = hash[1], C = hash[2], D = hash[3];
@@ -186,7 +186,7 @@ static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16])
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size)
void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 127;
ctx->length += size;
@@ -228,7 +228,7 @@ void rhash_sha512_update(sha512_ctx *ctx, const unsigned char *msg, size_t size)
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result)
void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 127) >> 3;
unsigned shift = ((unsigned)ctx->length & 7) * 8;
+4 -4
View File
@@ -20,10 +20,10 @@ typedef struct sha512_ctx
unsigned digest_length; /* length of the algorithm digest in bytes */
} sha512_ctx;
void rhash_sha384_init(sha512_ctx *ctx);
void rhash_sha512_init(sha512_ctx *ctx);
void rhash_sha512_update(sha512_ctx *ctx, const unsigned char* data, size_t length);
void rhash_sha512_final(sha512_ctx *ctx, unsigned char* result);
void rhash_sha384_init(sha512_ctx* ctx);
void rhash_sha512_init(sha512_ctx* ctx);
void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* data, size_t length);
void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
+20 -16
View File
@@ -2,29 +2,33 @@
#ifndef LIBRHASH_USTD_H
#define LIBRHASH_USTD_H
#if _MSC_VER >= 1300
#if _MSC_VER > 1000
# include <stddef.h> /* size_t for vc6.0 */
# define int64_t __int64
# define int32_t __int32
# define int16_t __int16
# define int8_t __int8
# define uint64_t unsigned __int64
# define uint32_t unsigned __int32
# define uint16_t unsigned __int16
# define uint8_t unsigned __int8
# if _MSC_VER >= 1600
/* Visual Studio >= 2010 has stdint.h */
# include <stdint.h>
# else
/* vc6.0 has bug with __int8, so using char instead */
typedef signed char int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
# endif /* _MSC_VER >= 1600 */
/* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */
#pragma warning(disable : 4996)
# pragma warning(disable : 4996)
#else /* _MSC_VER >= 1300 */
#else /* _MSC_VER > 1000 */
# include <stdint.h>
# include <unistd.h>
#endif /* _MSC_VER >= 1300 */
#if _MSC_VER <= 1300
# include <stdlib.h> /* size_t for vc6.0 */
#endif /* _MSC_VER <= 1300 */
#endif /* _MSC_VER > 1000 */
#endif /* LIBRHASH_USTD_H */
+1 -1
View File
@@ -20,7 +20,7 @@ extern "C" {
# define atomic_compare_and_swap(ptr, oldval, newval) atomic_cas_32(ptr, oldval, newval)
#else
/* pray that it will work */
# define atomic_compare_and_swap(ptr, oldval, newval) { if(*(ptr) == (oldval)) *(ptr) = (newval); }
# define atomic_compare_and_swap(ptr, oldval, newval) { if (*(ptr) == (oldval)) *(ptr) = (newval); }
# define NO_ATOMIC_BUILTINS
#endif