Added the BLAKE2 hash algorithm.

This commit is contained in:
LoRd_MuldeR 2015-02-01 21:03:28 +01:00
parent e581028182
commit 02be92208f
12 changed files with 1057 additions and 78 deletions

View File

@ -18,6 +18,7 @@
<ClCompile Include="$(SolutionDir)\tmp\$(ProjectName)\QRC_MUtilsData.cpp" />
<ClCompile Include="$(SolutionDir)\tmp\$(ProjectName)\MOC_UpdateChecker.cpp" />
<ClCompile Include="src\3rd_party\adler32\src\adler32.cpp" />
<ClCompile Include="src\3rd_party\blake2\src\blake2.cpp" />
<ClCompile Include="src\3rd_party\strnatcmp\src\strnatcmp.cpp" />
<ClCompile Include="src\CPUFeatures_Win32.cpp" />
<ClCompile Include="src\DLLMain.cpp" />
@ -25,9 +26,10 @@
<ClCompile Include="src\Global.cpp" />
<ClCompile Include="src\GUI.cpp" />
<ClCompile Include="src\GUI_Win32.cpp" />
<ClCompile Include="src\Hash_Blake2.cpp" />
<ClCompile Include="src\IPCChannel.cpp" />
<ClCompile Include="src\JobObject_Win32.cpp" />
<ClCompile Include="src\KeccakHash.cpp" />
<ClCompile Include="src\Hash_Keccak.cpp" />
<ClCompile Include="src\OSSupport_Win32.cpp" />
<ClCompile Include="src\Sound_Win32.cpp" />
<ClCompile Include="src\Startup.cpp" />
@ -43,9 +45,10 @@
<ClInclude Include="include\MUtils\Exception.h" />
<ClInclude Include="include\MUtils\Global.h" />
<ClInclude Include="include\MUtils\GUI.h" />
<ClInclude Include="include\MUtils\Hash_Blake2.h" />
<ClInclude Include="include\MUtils\IPCChannel.h" />
<ClInclude Include="include\MUtils\JobObject.h" />
<ClInclude Include="include\MUtils\KeccakHash.h" />
<ClInclude Include="include\MUtils\Hash_Keccak.h" />
<ClInclude Include="include\MUtils\OSSupport.h" />
<ClInclude Include="include\MUtils\Sound.h" />
<ClInclude Include="include\MUtils\Startup.h" />
@ -53,6 +56,7 @@
<ClInclude Include="include\MUtils\Terminal.h" />
<ClInclude Include="include\MUtils\Translation.h" />
<ClInclude Include="src\3rd_party\adler32\include\adler32.h" />
<ClInclude Include="src\3rd_party\blake2\include\blake2.h" />
<ClInclude Include="src\3rd_party\keccak\include\keccak_impl.h" />
<ClInclude Include="src\3rd_party\strnatcmp\include\strnatcmp.h" />
<ClInclude Include="src\DirLocker.h" />

View File

@ -39,9 +39,6 @@
<ClCompile Include="src\Version.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\KeccakHash.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\CPUFeatures_Win32.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -90,6 +87,15 @@
<ClCompile Include="$(SolutionDir)\tmp\$(ProjectName)\QRC_MUtilsData.cpp">
<Filter>Source Files\Generated</Filter>
</ClCompile>
<ClCompile Include="src\Hash_Keccak.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Hash_Blake2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\3rd_party\blake2\src\blake2.cpp">
<Filter>Source Files\3rd Party</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\CriticalSection_Win32.h">
@ -107,9 +113,6 @@
<ClInclude Include="include\MUtils\Version.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="include\MUtils\KeccakHash.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="src\DirLocker.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -155,6 +158,15 @@
<ClInclude Include="include\MUtils\Translation.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="include\MUtils\Hash_Blake2.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="include\MUtils\Hash_Keccak.h">
<Filter>Public Headers</Filter>
</ClInclude>
<ClInclude Include="src\3rd_party\blake2\include\blake2.h">
<Filter>Header Files\3rd Party</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="include\Mutils\UpdateChecker.h">

View File

@ -0,0 +1,67 @@
///////////////////////////////////////////////////////////////////////////////
// Simple x264 Launcher
// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// 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. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
/*
BLAKE2 reference source code package - reference C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
//MUtils
#include <MUtils/Global.h>
//Qt
#include <QByteArray>
#include <QFile>
namespace MUtils
{
namespace Hash
{
class MUTILS_API Blake2_Context;
class MUTILS_API Blake2
{
public:
Blake2(const char* key = NULL);
~Blake2(void);
void update(const QByteArray &data);
void update(QFile &file);
QByteArray finalize(const bool bAsHex = true);
private:
QByteArray m_hash;
Blake2_Context *const m_context;
bool m_finalized;
};
}
}

View File

@ -56,61 +56,64 @@
namespace MUtils
{
namespace Internal
namespace Hash
{
// Section from KeccakSponge.h
// needed here, since hashState needs to be explicitly 32-byte aligned and therefore can't be
// transformed into a class (in order to forward declarate) like in the other hash wrappers.
namespace KeccakImpl
namespace Internal
{
#define KeccakPermutationSize 1600
#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
#define KeccakMaximumRate 1536
#define KeccakMaximumRateInBytes (KeccakMaximumRate/8)
#if defined(__GNUC__)
#define ALIGN __attribute__ ((aligned(32)))
#elif defined(_MSC_VER)
#define ALIGN __declspec(align(32))
#else
#define ALIGN
#endif
ALIGN typedef struct spongeStateStruct
// Section from KeccakSponge.h
// needed here, since hashState needs to be explicitly 32-byte aligned and therefore can't be
// transformed into a class (in order to forward declarate) like in the other hash wrappers.
namespace KeccakImpl
{
ALIGN unsigned char state[KeccakPermutationSizeInBytes];
ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes];
unsigned int rate;
unsigned int capacity;
unsigned int bitsInQueue;
unsigned int fixedOutputLength;
int squeezing;
unsigned int bitsAvailableForSqueezing;
#define KeccakPermutationSize 1600
#define KeccakPermutationSizeInBytes (KeccakPermutationSize/8)
#define KeccakMaximumRate 1536
#define KeccakMaximumRateInBytes (KeccakMaximumRate/8)
#if defined(__GNUC__)
#define ALIGN __attribute__ ((aligned(32)))
#elif defined(_MSC_VER)
#define ALIGN __declspec(align(32))
#else
#define ALIGN
#endif
ALIGN typedef struct spongeStateStruct
{
ALIGN unsigned char state[KeccakPermutationSizeInBytes];
ALIGN unsigned char dataQueue[KeccakMaximumRateInBytes];
unsigned int rate;
unsigned int capacity;
unsigned int bitsInQueue;
unsigned int fixedOutputLength;
int squeezing;
unsigned int bitsAvailableForSqueezing;
}
spongeState;
typedef spongeState hashState;
}
spongeState;
typedef spongeState hashState;
// End Section from KeccakSponge.h
}
// End Section from KeccakSponge.h
class MUTILS_API Keccak
{
public:
enum HashBits {hb224, hb256, hb384, hb512};
Keccak();
~Keccak();
static bool selfTest(void);
bool init(HashBits hashBits=hb256);
bool addData(const QByteArray &data);
bool addData(const char *data, int size);
const QByteArray &finalize();
protected:
bool m_initialized;
Internal::KeccakImpl::hashState *m_state;
QByteArray m_hashResult;
};
}
class MUTILS_API KeccakHash
{
public:
enum HashBits {hb224, hb256, hb384, hb512};
KeccakHash();
~KeccakHash();
static bool selfTest(void);
bool init(HashBits hashBits=hb256);
bool addData(const QByteArray &data);
bool addData(const char *data, int size);
const QByteArray &finalize();
protected:
bool m_initialized;
Internal::KeccakImpl::hashState *m_state;
QByteArray m_hashResult;
};
};

121
src/3rd_party/blake2/COPYING.txt vendored Normal file
View File

@ -0,0 +1,121 @@
Creative Commons Legal Code
CC0 1.0 Universal
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
HEREUNDER.
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.
For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:
i. the right to reproduce, adapt, distribute, perform, display,
communicate, and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
likeness depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data
in a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation
thereof, including any amended or successor version of such
directive); and
vii. other similar, equivalent or corresponding rights throughout the
world based on applicable law or treaty, and any national
implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or
warranties of any kind concerning the Work, express, implied,
statutory or otherwise, including without limitation warranties of
title, merchantability, fitness for a particular purpose, non
infringement, or the absence of latent or other defects, accuracy, or
the present or absence of errors, whether or not discoverable, all to
the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without
limitation any person's Copyright and Related Rights in the Work.
Further, Affirmer disclaims responsibility for obtaining any necessary
consents, permissions or other rights required for any use of the
Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to
this CC0 or use of the Work.

19
src/3rd_party/blake2/README.txt vendored Normal file
View File

@ -0,0 +1,19 @@
this is the reference source code package of BLAKE2, which includes
ref/
C implementations of blake2b, blake2bp, blake2s, blake2sp, aimed at
portability and simplicity
sse/
C implementations of blake2b, blake2bp, blake2s, blake2sp, optimized
for speed on CPUs supporting SSE2, SSSE3, SSE4.1, AVX, or XOP
csharp/
C# implementation of blake2b
b2sum/
command line tool to hash files, based on the sse/ implementations
bench/
benchmark tool to measure cycles-per-byte speeds and produce graphs

93
src/3rd_party/blake2/include/blake2.h vendored Normal file
View File

@ -0,0 +1,93 @@
/*
BLAKE2 reference source code package - reference C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#pragma once
#ifndef __BLAKE2_H__
#define __BLAKE2_H__
#include <stddef.h>
#include <stdint.h>
#if defined(_MSC_VER)
#define ALIGN(x) __declspec(align(x))
#ifndef __cplusplus
#define inline __inline
#endif
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif
namespace MUtils
{
namespace Hash
{
namespace Internal
{
namespace Blake2Impl
{
enum blake2b_constant
{
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16
};
#pragma pack(push, 1)
typedef struct __blake2b_param
{
uint8_t digest_length; // 1
uint8_t key_length; // 2
uint8_t fanout; // 3
uint8_t depth; // 4
uint32_t leaf_length; // 8
uint64_t node_offset; // 16
uint8_t node_depth; // 17
uint8_t inner_length; // 18
uint8_t reserved[14]; // 32
uint8_t salt[BLAKE2B_SALTBYTES]; // 48
uint8_t personal[BLAKE2B_PERSONALBYTES]; // 64
} blake2b_param;
ALIGN( 64 ) typedef struct __blake2b_state
{
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
size_t buflen;
uint8_t last_node;
} blake2b_state;
#pragma pack(pop)
// Streaming API
int blake2b_init( blake2b_state *S, const uint8_t outlen );
int blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen );
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
int blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen );
int blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen );
// Simple API
int blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen );
static inline int blake2( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
{
return blake2b( out, in, key, outlen, inlen, keylen );
}
}
}
}
}
#endif

514
src/3rd_party/blake2/src/blake2.cpp vendored Normal file
View File

@ -0,0 +1,514 @@
/*
BLAKE2 reference source code package - reference C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "../include/blake2.h"
/*------------------------------------*/
/* blake2-impl.h */
/*------------------------------------*/
static inline uint32_t load32( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
return *( uint32_t * )( src );
#else
const uint8_t *p = ( uint8_t * )src;
uint32_t w = *p++;
w |= ( uint32_t )( *p++ ) << 8;
w |= ( uint32_t )( *p++ ) << 16;
w |= ( uint32_t )( *p++ ) << 24;
return w;
#endif
}
static inline uint64_t load64( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
return *( uint64_t * )( src );
#else
const uint8_t *p = ( uint8_t * )src;
uint64_t w = *p++;
w |= ( uint64_t )( *p++ ) << 8;
w |= ( uint64_t )( *p++ ) << 16;
w |= ( uint64_t )( *p++ ) << 24;
w |= ( uint64_t )( *p++ ) << 32;
w |= ( uint64_t )( *p++ ) << 40;
w |= ( uint64_t )( *p++ ) << 48;
w |= ( uint64_t )( *p++ ) << 56;
return w;
#endif
}
static inline void store32( void *dst, uint32_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
*( uint32_t * )( dst ) = w;
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w;
#endif
}
static inline void store64( void *dst, uint64_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
*( uint64_t * )( dst ) = w;
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w;
#endif
}
static inline uint64_t load48( const void *src )
{
const uint8_t *p = ( const uint8_t * )src;
uint64_t w = *p++;
w |= ( uint64_t )( *p++ ) << 8;
w |= ( uint64_t )( *p++ ) << 16;
w |= ( uint64_t )( *p++ ) << 24;
w |= ( uint64_t )( *p++ ) << 32;
w |= ( uint64_t )( *p++ ) << 40;
return w;
}
static inline void store48( void *dst, uint64_t w )
{
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w;
}
static inline uint32_t rotl32( const uint32_t w, const unsigned c )
{
return ( w << c ) | ( w >> ( 32 - c ) );
}
static inline uint64_t rotl64( const uint64_t w, const unsigned c )
{
return ( w << c ) | ( w >> ( 64 - c ) );
}
static inline uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
}
static inline uint64_t rotr64( const uint64_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 64 - c ) );
}
/* prevents compiler optimizing out memset() */
static inline void secure_zero_memory( void *v, size_t n )
{
volatile uint8_t *p = ( volatile uint8_t * )v;
while( n-- ) *p++ = 0;
}
/*------------------------------------*/
/* blake2b-ref.c */
/*------------------------------------*/
static const uint64_t blake2b_IV[8] =
{
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
};
static const uint8_t blake2b_sigma[12][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};
static inline int blake2b_set_lastnode( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S )
{
S->f[1] = ~0ULL;
return 0;
}
static inline int blake2b_clear_lastnode( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S )
{
S->f[1] = 0ULL;
return 0;
}
/* Some helper functions, not necessarily useful */
static inline int blake2b_set_lastblock( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S )
{
if( S->last_node ) blake2b_set_lastnode( S );
S->f[0] = ~0ULL;
return 0;
}
static inline int blake2b_clear_lastblock( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S )
{
if( S->last_node ) blake2b_clear_lastnode( S );
S->f[0] = 0ULL;
return 0;
}
static inline int blake2b_increment_counter( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S, const uint64_t inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
return 0;
}
// Parameter-related functions
static inline int blake2b_param_set_digest_length( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t digest_length )
{
P->digest_length = digest_length;
return 0;
}
static inline int blake2b_param_set_fanout( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t fanout )
{
P->fanout = fanout;
return 0;
}
static inline int blake2b_param_set_max_depth( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t depth )
{
P->depth = depth;
return 0;
}
static inline int blake2b_param_set_leaf_length( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint32_t leaf_length )
{
store32( &P->leaf_length, leaf_length );
return 0;
}
static inline int blake2b_param_set_node_offset( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint64_t node_offset )
{
store64( &P->node_offset, node_offset );
return 0;
}
static inline int blake2b_param_set_node_depth( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t node_depth )
{
P->node_depth = node_depth;
return 0;
}
static inline int blake2b_param_set_inner_length( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t inner_length )
{
P->inner_length = inner_length;
return 0;
}
static inline int blake2b_param_set_salt( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t salt[MUtils::Hash::Internal::Blake2Impl::BLAKE2B_SALTBYTES] )
{
memcpy( P->salt, salt, MUtils::Hash::Internal::Blake2Impl::BLAKE2B_SALTBYTES );
return 0;
}
static inline int blake2b_param_set_personal( MUtils::Hash::Internal::Blake2Impl::blake2b_param *P, const uint8_t personal[MUtils::Hash::Internal::Blake2Impl::BLAKE2B_PERSONALBYTES] )
{
memcpy( P->personal, personal, MUtils::Hash::Internal::Blake2Impl::BLAKE2B_PERSONALBYTES );
return 0;
}
static inline int blake2b_init0( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S )
{
int i;
memset( S, 0, sizeof( MUtils::Hash::Internal::Blake2Impl::blake2b_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
return 0;
}
/* init xors IV with input parameter block */
int MUtils::Hash::Internal::Blake2Impl::blake2b_init_param( blake2b_state *S, const blake2b_param *P )
{
uint8_t *p;
size_t i;
blake2b_init0( S );
p = ( uint8_t * )( P );
/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
return 0;
}
int MUtils::Hash::Internal::Blake2Impl::blake2b_init( blake2b_state *S, const uint8_t outlen )
{
blake2b_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
P->digest_length = outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store64( &P->node_offset, 0 );
P->node_depth = 0;
P->inner_length = 0;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
return blake2b_init_param( S, P );
}
int MUtils::Hash::Internal::Blake2Impl::blake2b_init_key( blake2b_state *S, const uint8_t outlen, const void *key, const uint8_t keylen )
{
blake2b_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
P->digest_length = outlen;
P->key_length = keylen;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store64( &P->node_offset, 0 );
P->node_depth = 0;
P->inner_length = 0;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
if( blake2b_init_param( S, P ) < 0 ) return -1;
{
uint8_t block[BLAKE2B_BLOCKBYTES];
memset( block, 0, BLAKE2B_BLOCKBYTES );
memcpy( block, key, keylen );
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}
static int blake2b_compress( MUtils::Hash::Internal::Blake2Impl::blake2b_state *S, const uint8_t block[MUtils::Hash::Internal::Blake2Impl::BLAKE2B_BLOCKBYTES] )
{
uint64_t m[16];
uint64_t v[16];
int i;
for( i = 0; i < 16; ++i )
m[i] = load64( block + i * sizeof( m[i] ) );
for( i = 0; i < 8; ++i )
v[i] = S->h[i];
v[ 8] = blake2b_IV[0];
v[ 9] = blake2b_IV[1];
v[10] = blake2b_IV[2];
v[11] = blake2b_IV[3];
v[12] = S->t[0] ^ blake2b_IV[4];
v[13] = S->t[1] ^ blake2b_IV[5];
v[14] = S->f[0] ^ blake2b_IV[6];
v[15] = S->f[1] ^ blake2b_IV[7];
#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
d = rotr64(d ^ a, 32); \
c = c + d; \
b = rotr64(b ^ c, 24); \
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
d = rotr64(d ^ a, 16); \
c = c + d; \
b = rotr64(b ^ c, 63); \
} while(0)
#define ROUND(r) \
do { \
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
} while(0)
ROUND( 0 );
ROUND( 1 );
ROUND( 2 );
ROUND( 3 );
ROUND( 4 );
ROUND( 5 );
ROUND( 6 );
ROUND( 7 );
ROUND( 8 );
ROUND( 9 );
ROUND( 10 );
ROUND( 11 );
for( i = 0; i < 8; ++i )
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
#undef G
#undef ROUND
return 0;
}
/* inlen now in bytes */
int MUtils::Hash::Internal::Blake2Impl::blake2b_update( blake2b_state *S, const uint8_t *in, uint64_t inlen )
{
while( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = 2 * BLAKE2B_BLOCKBYTES - left;
if( inlen > fill )
{
memcpy( S->buf + left, in, fill ); // Fill buffer
S->buflen += fill;
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf ); // Compress
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); // Shift buffer left
S->buflen -= BLAKE2B_BLOCKBYTES;
in += fill;
inlen -= fill;
}
else // inlen <= fill
{
memcpy( S->buf + left, in, (size_t) inlen );
S->buflen = (size_t)(S->buflen + inlen); // Be lazy, do not compress
in += inlen;
inlen -= inlen;
}
}
return 0;
}
/* Is this correct? */
int MUtils::Hash::Internal::Blake2Impl::blake2b_final( blake2b_state *S, uint8_t *out, uint8_t outlen )
{
int i;
uint8_t buffer[BLAKE2B_OUTBYTES];
if( S->buflen > BLAKE2B_BLOCKBYTES )
{
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf );
S->buflen -= BLAKE2B_BLOCKBYTES;
memcpy( S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen );
}
blake2b_increment_counter( S, S->buflen );
blake2b_set_lastblock( S );
memset( S->buf + S->buflen, 0, 2 * BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
blake2b_compress( S, S->buf );
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
memcpy( out, buffer, outlen );
return 0;
}
/* inlen, at least, should be uint64_t. Others can be size_t. */
int MUtils::Hash::Internal::Blake2Impl::blake2b( uint8_t *out, const void *in, const void *key, const uint8_t outlen, const uint64_t inlen, uint8_t keylen )
{
blake2b_state S[1];
/* Verify parameters */
if ( NULL == in ) return -1;
if ( NULL == out ) return -1;
if( NULL == key ) keylen = 0;
if( keylen > 0 )
{
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
}
else
{
if( blake2b_init( S, outlen ) < 0 ) return -1;
}
blake2b_update( S, ( uint8_t * )in, inlen );
blake2b_final( S, out, outlen );
return 0;
}
#if defined(BLAKE2B_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( int argc, char **argv )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[KAT_LENGTH];
for( size_t i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
for( size_t i = 0; i < KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES );
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
puts( "error" );
return -1;
}
}
puts( "ok" );
return 0;
}
#endif

View File

@ -19,6 +19,7 @@
***************************************************************************/
namespace MUtils {
namespace Hash {
namespace Internal {
namespace KeccakImpl {
@ -1999,5 +2000,6 @@ HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen,
} // end of namespace KeccakImpl
} // end of namespace Internal
} // end of namespace Hash
} // end of namespace MUtils

143
src/Hash_Blake2.cpp Normal file
View File

@ -0,0 +1,143 @@
///////////////////////////////////////////////////////////////////////////////
// Simple x264 Launcher
// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// 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. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
/*
BLAKE2 reference source code package - reference C implementations
Written in 2012 by Samuel Neves <sneves@dei.uc.pt>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with
this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
//MUtils
#include <MUtils/Hash_Blake2.h>
#include <MUtils/Exception.h>
//Internal
#include "3rd_party/blake2/include/blake2.h"
#include <malloc.h>
#include <string.h>
#include <stdexcept>
static const size_t HASH_SIZE = 64;
class MUtils::Hash::Blake2_Context
{
friend Blake2;
Blake2_Context(void)
{
if(!(state = (MUtils::Hash::Internal::Blake2Impl::blake2b_state*) _aligned_malloc(sizeof(MUtils::Hash::Internal::Blake2Impl::blake2b_state), 64)))
{
MUTILS_THROW("Aligend malloc has failed!");
}
memset(state, 0, sizeof(MUtils::Hash::Internal::Blake2Impl::blake2b_state));
}
~Blake2_Context(void)
{
memset(state, 0, sizeof(MUtils::Hash::Internal::Blake2Impl::blake2b_state));
_aligned_free(state);
}
private:
MUtils::Hash::Internal::Blake2Impl::blake2b_state *state;
};
MUtils::Hash::Blake2::Blake2(const char* key)
:
m_hash(HASH_SIZE, '\0'),
m_context(new Blake2_Context()),
m_finalized(false)
{
if(key && key[0])
{
blake2b_init_key(m_context->state, HASH_SIZE, key, strlen(key));
}
else
{
blake2b_init(m_context->state, HASH_SIZE);
}
}
MUtils::Hash::Blake2::~Blake2(void)
{
delete m_context;
}
void MUtils::Hash::Blake2::update(const QByteArray &data)
{
if(m_finalized)
{
MUTILS_THROW("BLAKE2 was already finalized!");
}
if(data.size() > 0)
{
if(blake2b_update(m_context->state, (const uint8_t*) data.constData(), data.size()) != 0)
{
MUTILS_THROW("BLAKE2 internal error!");
}
}
}
void MUtils::Hash::Blake2::update(QFile &file)
{
bool okay = false;
for(;;)
{
QByteArray data = file.read(16384);
if(data.size() > 0)
{
okay = true;
update(data);
continue;
}
break;
}
if(!okay)
{
qWarning("[QBlake2Checksum] Could not ready any data from file!");
}
}
QByteArray MUtils::Hash::Blake2::finalize(const bool bAsHex)
{
if(!m_finalized)
{
if(blake2b_final(m_context->state, (uint8_t*) m_hash.data(), m_hash.size()) != 0)
{
MUTILS_THROW("BLAKE2 internal error!");
}
m_finalized = true;
}
return bAsHex ? m_hash.toHex() : m_hash;
}

View File

@ -44,24 +44,24 @@
** Date: 12.01.12 **
****************************************************************************/
#include <MUtils/KeccakHash.h>
#include <MUtils/Hash_Keccak.h>
#include <QDebug>
#include "3rd_party/keccak/include/keccak_impl.h"
MUtils::KeccakHash::KeccakHash()
MUtils::Hash::Keccak::Keccak()
{
m_initialized = false;
m_state = (MUtils::Internal::KeccakImpl::hashState*) _aligned_malloc(sizeof(MUtils::Internal::KeccakImpl::hashState), 32);
m_state = (MUtils::Hash::Internal::KeccakImpl::hashState*) _aligned_malloc(sizeof(MUtils::Hash::Internal::KeccakImpl::hashState), 32);
if(!m_state)
{
throw "[MUtils::KeccakHash] Error: _aligned_malloc() has failed, probably out of heap space!";
}
memset(m_state, 0, sizeof(MUtils::Internal::KeccakImpl::hashState));
memset(m_state, 0, sizeof(MUtils::Hash::Internal::KeccakImpl::hashState));
m_hashResult.clear();
}
MUtils::KeccakHash::~KeccakHash()
MUtils::Hash::Keccak::~Keccak()
{
m_hashResult.clear();
@ -72,7 +72,7 @@ MUtils::KeccakHash::~KeccakHash()
}
}
bool MUtils::KeccakHash::init(HashBits hashBits)
bool MUtils::Hash::Keccak::init(HashBits hashBits)
{
if(m_initialized)
{
@ -81,7 +81,7 @@ bool MUtils::KeccakHash::init(HashBits hashBits)
}
m_hashResult.clear();
memset(m_state, 0, sizeof(MUtils::Internal::KeccakImpl::hashState));
memset(m_state, 0, sizeof(MUtils::Hash::Internal::KeccakImpl::hashState));
int hashBitLength = 0;
switch (hashBits)
@ -93,7 +93,7 @@ bool MUtils::KeccakHash::init(HashBits hashBits)
default: throw "Invalid hash length!!";
}
if(MUtils::Internal::KeccakImpl::Init(m_state, hashBitLength) != MUtils::Internal::KeccakImpl::SUCCESS)
if(MUtils::Hash::Internal::KeccakImpl::Init(m_state, hashBitLength) != MUtils::Hash::Internal::KeccakImpl::SUCCESS)
{
qWarning("KeccakImpl::Init() has failed unexpectedly!");
return false;
@ -105,12 +105,12 @@ bool MUtils::KeccakHash::init(HashBits hashBits)
return true;
}
bool MUtils::KeccakHash::addData(const QByteArray &data)
bool MUtils::Hash::Keccak::addData(const QByteArray &data)
{
return addData(data.constData(), data.size());
}
bool MUtils::KeccakHash::addData(const char *data, int size)
bool MUtils::Hash::Keccak::addData(const char *data, int size)
{
if(!m_initialized)
{
@ -118,7 +118,7 @@ bool MUtils::KeccakHash::addData(const char *data, int size)
return false;
}
if(MUtils::Internal::KeccakImpl::Update(m_state, (MUtils::Internal::KeccakImpl::BitSequence*)data, size*8) != MUtils::Internal::KeccakImpl::SUCCESS)
if(MUtils::Hash::Internal::KeccakImpl::Update(m_state, (MUtils::Hash::Internal::KeccakImpl::BitSequence*)data, size*8) != MUtils::Hash::Internal::KeccakImpl::SUCCESS)
{
qWarning("KeccakImpl::Update() has failed unexpectedly!");
m_hashResult.clear();
@ -129,7 +129,7 @@ bool MUtils::KeccakHash::addData(const char *data, int size)
return true;
}
const QByteArray &MUtils::KeccakHash::finalize()
const QByteArray &MUtils::Hash::Keccak::finalize()
{
if(!m_initialized)
{
@ -138,7 +138,7 @@ const QByteArray &MUtils::KeccakHash::finalize()
return m_hashResult;
}
if(MUtils::Internal::KeccakImpl::Final(m_state, (MUtils::Internal::KeccakImpl::BitSequence*)m_hashResult.data()) != MUtils::Internal::KeccakImpl::SUCCESS)
if(MUtils::Hash::Internal::KeccakImpl::Final(m_state, (MUtils::Hash::Internal::KeccakImpl::BitSequence*)m_hashResult.data()) != MUtils::Hash::Internal::KeccakImpl::SUCCESS)
{
qWarning("KeccakImpl::Final() has failed unexpectedly!");
m_hashResult.clear();
@ -148,13 +148,13 @@ const QByteArray &MUtils::KeccakHash::finalize()
return m_hashResult;
}
bool MUtils::KeccakHash::selfTest(void)
bool MUtils::Hash::Keccak::selfTest(void)
{
MUtils::KeccakHash hash;
MUtils::Hash::Keccak hash;
const QByteArray input("The quick brown fox jumps over the lazy dog");
bool passed[4] = {false, false, false, false};
if(hash.init(MUtils::KeccakHash::hb224))
if(hash.init(MUtils::Hash::Keccak::hb224))
{
if(hash.addData(input))
{
@ -167,7 +167,7 @@ bool MUtils::KeccakHash::selfTest(void)
}
}
if(hash.init(MUtils::KeccakHash::hb256))
if(hash.init(MUtils::Hash::Keccak::hb256))
{
if(hash.addData(input))
{
@ -180,7 +180,7 @@ bool MUtils::KeccakHash::selfTest(void)
}
}
if(hash.init(MUtils::KeccakHash::hb384))
if(hash.init(MUtils::Hash::Keccak::hb384))
{
if(hash.addData(input))
{
@ -193,7 +193,7 @@ bool MUtils::KeccakHash::selfTest(void)
}
}
if(hash.init(MUtils::KeccakHash::hb512))
if(hash.init(MUtils::Hash::Keccak::hb512))
{
if(hash.addData(input))
{

View File

@ -588,6 +588,7 @@ bool UpdateChecker::checkSignature(const QString &file, const QString &signature
qWarning("CheckSignature: File and signature should be in same folder!");
return false;
}
if(QFileInfo(file).absolutePath().compare(QFileInfo(m_binaryKeys).absolutePath(), Qt::CaseInsensitive) != 0)
{
qWarning("CheckSignature: File and keyring should be in same folder!");