mirror of
https://github.com/BLAKE2/libb2
synced 2024-11-26 08:53:49 +01:00
init
This commit is contained in:
parent
a8b3f1469c
commit
564832de5e
121
COPYING
Executable file
121
COPYING
Executable 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.
|
5
Makefile.am
Normal file
5
Makefile.am
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
|
||||||
|
EXTRA_DIST = COPYING
|
||||||
|
|
||||||
|
SUBDIRS = src
|
2
autogen.sh
Executable file
2
autogen.sh
Executable file
@ -0,0 +1,2 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
autoreconf -fvi
|
13
clean.sh
Executable file
13
clean.sh
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
make maintainer-clean
|
||||||
|
rm -rf Makefile.in\
|
||||||
|
aclocal.m4\
|
||||||
|
config.guess\
|
||||||
|
config.sub\
|
||||||
|
configure\
|
||||||
|
depcomp\
|
||||||
|
install-sh\
|
||||||
|
ltmain.sh\
|
||||||
|
missing\
|
||||||
|
src/Makefile.in\
|
||||||
|
src/config.h.in
|
||||||
|
|
76
configure.ac
Normal file
76
configure.ac
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
AC_PREREQ([2.61])
|
||||||
|
AC_INIT([libb2], [0.97], [contact@blake2.net], [libb2], [https://blake2.net])
|
||||||
|
AC_CONFIG_SRCDIR([src/blake2b.c])
|
||||||
|
AC_CONFIG_HEADERS([src/config.h])
|
||||||
|
AM_INIT_AUTOMAKE([foreign 1.9])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
|
B2_LIBRARY_VERSION=1:2:0 # interface, revision, age
|
||||||
|
AC_SUBST(B2_LIBRARY_VERSION)
|
||||||
|
|
||||||
|
AC_LANG_C
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_CC_C99
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([stddef.h stdint.h stdlib.h string.h])
|
||||||
|
AC_OPENMP
|
||||||
|
AX_CHECK_ALIGNED_ACCESS_REQUIRED
|
||||||
|
# AX_FORCEINLINE()
|
||||||
|
AC_C_BIGENDIAN(
|
||||||
|
[],
|
||||||
|
AC_DEFINE(NATIVE_LITTLE_ENDIAN, 1, [machine is little-endian]),
|
||||||
|
AC_MSG_ERROR(unknown endianness),
|
||||||
|
AC_MSG_ERROR(universal endianness not supported)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_INLINE
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_UINT32_T
|
||||||
|
AC_TYPE_UINT64_T
|
||||||
|
AC_TYPE_UINT8_T
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
AC_CHECK_FUNCS([memset])
|
||||||
|
|
||||||
|
dnl AM_PROG_AR
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
dnl LT_INIT
|
||||||
|
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(fat,
|
||||||
|
AC_HELP_STRING([--enable-fat],
|
||||||
|
[build a fat binary on systems that support it [[default=no]]]),
|
||||||
|
[case $enableval in
|
||||||
|
yes|no) ;;
|
||||||
|
*) AC_MSG_ERROR([bad value $enableval for --enable-fat, need yes or no]) ;;
|
||||||
|
esac],
|
||||||
|
[enable_fat=no]
|
||||||
|
)
|
||||||
|
|
||||||
|
AX_CHECK_COMPILE_FLAG([-O3], [CFLAGS=-O3])
|
||||||
|
|
||||||
|
if test $enable_fat == "yes"; then
|
||||||
|
dnl Fat build needs compiler who knows all the possible instruction sets
|
||||||
|
AX_CHECK_COMPILE_FLAG([-msse2], [], AC_MSG_ERROR([Compiler does not know -msse2.]))
|
||||||
|
AX_CHECK_COMPILE_FLAG([-mssse3], [], AC_MSG_ERROR([Compiler does not know -mssse3.]))
|
||||||
|
AX_CHECK_COMPILE_FLAG([-msse4.1], [], AC_MSG_ERROR([Compiler does not know -msse4.1.]))
|
||||||
|
AX_CHECK_COMPILE_FLAG([-mavx], [], AC_MSG_ERROR([Compiler does not know -mavx.]))
|
||||||
|
AX_CHECK_COMPILE_FLAG([-mxop], [], AC_MSG_ERROR([Compiler does not know -mxop.]))
|
||||||
|
else
|
||||||
|
AX_EXT
|
||||||
|
CFLAGS="${CFLAGS} -march=native"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $host_os in
|
||||||
|
*mingw*) LDFLAGS="${LDFLAGS} -no-undefined" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AM_CONDITIONAL([USE_FAT], [test "$enable_fat" = "yes"])
|
||||||
|
dnl Only move away from ref with SSSE3; SSE2 is generally slower
|
||||||
|
AM_CONDITIONAL([USE_SSE], [test "$ax_cv_have_ssse3_ext" = "yes"])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile
|
||||||
|
src/Makefile
|
||||||
|
])
|
||||||
|
AC_OUTPUT
|
84
m4/ax_check_aligned_access_required.m4
Normal file
84
m4/ax_check_aligned_access_required.m4
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# ====================================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_check_aligned_access_required.html
|
||||||
|
# ====================================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AC_CHECK_ALIGNED_ACCESS_REQUIRED
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# While the x86 CPUs allow access to memory objects to be unaligned it
|
||||||
|
# happens that most of the modern designs require objects to be aligned -
|
||||||
|
# or they will fail with a buserror. That mode is quite known by
|
||||||
|
# big-endian machines (sparc, etc) however the alpha cpu is little-
|
||||||
|
# endian.
|
||||||
|
#
|
||||||
|
# The following function will test for aligned access to be required and
|
||||||
|
# set a config.h define HAVE_ALIGNED_ACCESS_REQUIRED (name derived by
|
||||||
|
# standard usage). Structures loaded from a file (or mmapped to memory)
|
||||||
|
# should be accessed per-byte in that case to avoid segfault type errors.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 7
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CHECK_ALIGNED_ACCESS_REQUIRED],
|
||||||
|
[AC_CACHE_CHECK([if pointers to integers require aligned access],
|
||||||
|
[ax_cv_have_aligned_access_required],
|
||||||
|
[AC_TRY_RUN([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
char* string = malloc(40);
|
||||||
|
int i;
|
||||||
|
for (i=0; i < 40; i++) string[[i]] = i;
|
||||||
|
{
|
||||||
|
void* s = string;
|
||||||
|
int* p = s+1;
|
||||||
|
int* q = s+2;
|
||||||
|
|
||||||
|
if (*p == *q) { return 1; }
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[ax_cv_have_aligned_access_required=yes],
|
||||||
|
[ax_cv_have_aligned_access_required=no],
|
||||||
|
[ax_cv_have_aligned_access_required=no])
|
||||||
|
])
|
||||||
|
if test "$ax_cv_have_aligned_access_required" = yes ; then
|
||||||
|
AC_DEFINE([HAVE_ALIGNED_ACCESS_REQUIRED], [1],
|
||||||
|
[Define if pointers to integers require aligned access])
|
||||||
|
fi
|
||||||
|
])
|
73
m4/ax_check_compile_flag.m4
Normal file
73
m4/ax_check_compile_flag.m4
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check whether the given FLAG works with the current language's compiler
|
||||||
|
# or gives an error. (Warnings, however, are ignored)
|
||||||
|
#
|
||||||
|
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||||
|
# success/failure.
|
||||||
|
#
|
||||||
|
# If EXTRA-FLAGS is defined, it is added to the current language's default
|
||||||
|
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
|
||||||
|
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
|
||||||
|
# force the compiler to issue an error when a bad flag is given.
|
||||||
|
#
|
||||||
|
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||||
|
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
|
||||||
|
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
|
||||||
|
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
|
||||||
|
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
|
||||||
|
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
|
||||||
|
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>]],
|
||||||
|
[[char x[42U], fodder = 0;if (fodder > -1000 && fgets(x,1000,stdin)) puts(x)]])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[no])])
|
||||||
|
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
|
||||||
|
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
|
||||||
|
[m4_default([$2], :)],
|
||||||
|
[m4_default([$3], :)])
|
||||||
|
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||||
|
])dnl AX_CHECK_COMPILE_FLAGS
|
71
m4/ax_check_link_flag.m4
Normal file
71
m4/ax_check_link_flag.m4
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Check whether the given FLAG works with the linker or gives an error.
|
||||||
|
# (Warnings, however, are ignored)
|
||||||
|
#
|
||||||
|
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
|
||||||
|
# success/failure.
|
||||||
|
#
|
||||||
|
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
|
||||||
|
# when the check is done. The check is thus made with the flags: "LDFLAGS
|
||||||
|
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
|
||||||
|
# issue an error when a bad flag is given.
|
||||||
|
#
|
||||||
|
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
|
||||||
|
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
|
||||||
|
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AC_DEFUN([AX_CHECK_LINK_FLAG],
|
||||||
|
[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
|
||||||
|
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
|
||||||
|
ax_check_save_flags=$LDFLAGS
|
||||||
|
LDFLAGS="$LDFLAGS $4 $1"
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM()],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[yes])],
|
||||||
|
[AS_VAR_SET(CACHEVAR,[no])])
|
||||||
|
LDFLAGS=$ax_check_save_flags])
|
||||||
|
AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes],
|
||||||
|
[m4_default([$2], :)],
|
||||||
|
[m4_default([$3], :)])
|
||||||
|
AS_VAR_POPDEF([CACHEVAR])dnl
|
||||||
|
])dnl AX_CHECK_LINK_FLAGS
|
213
m4/ax_ext.m4
Normal file
213
m4/ax_ext.m4
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_ext.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_EXT
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Find supported SIMD extensions by requesting cpuid. When an SIMD
|
||||||
|
# extension is found, the -m"simdextensionname" is added to SIMD_FLAGS if
|
||||||
|
# compilator supports it. For example, if "sse2" is available, then
|
||||||
|
# "-msse2" is added to SIMD_FLAGS.
|
||||||
|
#
|
||||||
|
# This macro calls:
|
||||||
|
#
|
||||||
|
# AC_SUBST(SIMD_FLAGS)
|
||||||
|
#
|
||||||
|
# And defines:
|
||||||
|
#
|
||||||
|
# HAVE_MMX / HAVE_SSE / HAVE_SSE2 / HAVE_SSE3 / HAVE_SSSE3 / HAVE_SSE4.1 / HAVE_SSE4.2 / HAVE_AVX
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2007 Christophe Tournayre <turn3r@users.sourceforge.net>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 10
|
||||||
|
|
||||||
|
AC_DEFUN([AX_EXT],
|
||||||
|
[
|
||||||
|
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||||
|
|
||||||
|
case $host_cpu in
|
||||||
|
powerpc*)
|
||||||
|
AC_CACHE_CHECK([whether altivec is supported], [ax_cv_have_altivec_ext],
|
||||||
|
[
|
||||||
|
if test `/usr/sbin/sysctl -a 2>/dev/null| grep -c hw.optional.altivec` != 0; then
|
||||||
|
if test `/usr/sbin/sysctl -n hw.optional.altivec` = 1; then
|
||||||
|
ax_cv_have_altivec_ext=yes
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "$ax_cv_have_altivec_ext" = yes; then
|
||||||
|
AC_DEFINE(HAVE_ALTIVEC,,[Support Altivec instructions])
|
||||||
|
AX_CHECK_COMPILE_FLAG(-faltivec, SIMD_FLAGS="$SIMD_FLAGS -faltivec", [])
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
i[[3456]]86*|x86_64*)
|
||||||
|
|
||||||
|
AC_REQUIRE([AX_GCC_X86_CPUID])
|
||||||
|
|
||||||
|
AX_GCC_X86_CPUID(0x00000001)
|
||||||
|
ecx=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 3`
|
||||||
|
edx=`echo $ax_cv_gcc_x86_cpuid_0x00000001 | cut -d ":" -f 4`
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether mmx is supported], [ax_cv_have_mmx_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_mmx_ext=no
|
||||||
|
if test "$((0x$edx>>23&0x01))" = 1; then
|
||||||
|
ax_cv_have_mmx_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether sse is supported], [ax_cv_have_sse_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_sse_ext=no
|
||||||
|
if test "$((0x$edx>>25&0x01))" = 1; then
|
||||||
|
ax_cv_have_sse_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether sse2 is supported], [ax_cv_have_sse2_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_sse2_ext=no
|
||||||
|
if test "$((0x$edx>>26&0x01))" = 1; then
|
||||||
|
ax_cv_have_sse2_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether sse3 is supported], [ax_cv_have_sse3_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_sse3_ext=no
|
||||||
|
if test "$((0x$ecx&0x01))" = 1; then
|
||||||
|
ax_cv_have_sse3_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether ssse3 is supported], [ax_cv_have_ssse3_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_ssse3_ext=no
|
||||||
|
if test "$((0x$ecx>>9&0x01))" = 1; then
|
||||||
|
ax_cv_have_ssse3_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether sse4.1 is supported], [ax_cv_have_sse41_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_sse41_ext=no
|
||||||
|
if test "$((0x$ecx>>19&0x01))" = 1; then
|
||||||
|
ax_cv_have_sse41_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether sse4.2 is supported], [ax_cv_have_sse42_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_sse42_ext=no
|
||||||
|
if test "$((0x$ecx>>20&0x01))" = 1; then
|
||||||
|
ax_cv_have_sse42_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([whether avx is supported], [ax_cv_have_avx_ext],
|
||||||
|
[
|
||||||
|
ax_cv_have_avx_ext=no
|
||||||
|
if test "$((0x$ecx>>28&0x01))" = 1; then
|
||||||
|
ax_cv_have_avx_ext=yes
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "$ax_cv_have_mmx_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-mmmx, ax_cv_support_mmx_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_mmx_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -mmmx"
|
||||||
|
AC_DEFINE(HAVE_MMX,,[Support mmx instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support mmx instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_sse_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-msse, ax_cv_support_sse_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_sse_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -msse"
|
||||||
|
AC_DEFINE(HAVE_SSE,,[Support SSE (Streaming SIMD Extensions) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support sse instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_sse2_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-msse2, ax_cv_support_sse2_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_sse2_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -msse2"
|
||||||
|
AC_DEFINE(HAVE_SSE2,,[Support SSE2 (Streaming SIMD Extensions 2) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support sse2 instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_sse3_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-msse3, ax_cv_support_sse3_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_sse3_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -msse3"
|
||||||
|
AC_DEFINE(HAVE_SSE3,,[Support SSE3 (Streaming SIMD Extensions 3) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support sse3 instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_ssse3_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-mssse3, ax_cv_support_ssse3_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_ssse3_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -mssse3"
|
||||||
|
AC_DEFINE(HAVE_SSSE3,,[Support SSSE3 (Supplemental Streaming SIMD Extensions 3) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support ssse3 instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_sse41_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-msse4.1, ax_cv_support_sse41_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_sse41_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -msse4.1"
|
||||||
|
AC_DEFINE(HAVE_SSE4_1,,[Support SSSE4.1 (Streaming SIMD Extensions 4.1) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support sse4.1 instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_sse42_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-msse4.2, ax_cv_support_sse42_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_sse42_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -msse4.2"
|
||||||
|
AC_DEFINE(HAVE_SSE4_2,,[Support SSSE4.2 (Streaming SIMD Extensions 4.2) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support sse4.2 instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$ax_cv_have_avx_ext" = yes; then
|
||||||
|
AX_CHECK_COMPILE_FLAG(-mavx, ax_cv_support_avx_ext=yes, [])
|
||||||
|
if test x"$ax_cv_support_avx_ext" = x"yes"; then
|
||||||
|
SIMD_FLAGS="$SIMD_FLAGS -mavx"
|
||||||
|
AC_DEFINE(HAVE_AVX,,[Support AVX (Advanced Vector Extensions) instructions])
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Your processor support avx instructions but not your compilor, can you try another compilor ?])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
AC_SUBST(SIMD_FLAGS)
|
||||||
|
])
|
60
m4/ax_forceinline.m4
Normal file
60
m4/ax_forceinline.m4
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_forceinline.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_FORCEINLINE()
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# Provides a test for C compiler support of forced inlining. If usable,
|
||||||
|
# #define FORCEINLINE to the appropriate force inline keyword. Otherwise
|
||||||
|
# #define FORCEINLINE to be 'inline'.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk>
|
||||||
|
# Copyright (c) 2009 Rhys Ulerich <rhys.ulerich@gmail.com>
|
||||||
|
#
|
||||||
|
# Copying and distribution of this file, with or without modification, are
|
||||||
|
# permitted in any medium without royalty provided the copyright notice
|
||||||
|
# and this notice are preserved. This file is offered as-is, without any
|
||||||
|
# warranty.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
AC_DEFUN([AX_FORCEINLINE], [
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AC_MSG_CHECKING(for forced inline keyword)
|
||||||
|
AC_CACHE_VAL(ac_cv_forceinline, [
|
||||||
|
ax_forceinline_keywords="__forceinline inline none"
|
||||||
|
for ax_forceinline_keyword in $ax_forceinline_keywords; do
|
||||||
|
case $ax_forceinline_keyword in
|
||||||
|
none) ac_cv_forceinline=none ; break ;;
|
||||||
|
*)
|
||||||
|
AC_TRY_COMPILE(
|
||||||
|
[#include <stdlib.h>
|
||||||
|
] $ax_forceinline_keyword [
|
||||||
|
static void
|
||||||
|
foo(void) {
|
||||||
|
exit(1);
|
||||||
|
}],
|
||||||
|
[],
|
||||||
|
[ac_cv_forceinline=$ax_forceinline_keyword ; break],
|
||||||
|
ac_cv_forceinline=none
|
||||||
|
)
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
])
|
||||||
|
|
||||||
|
if test "$ac_cv_forceinline" = "none"; then
|
||||||
|
ax_forceinline_keyword=
|
||||||
|
else
|
||||||
|
ax_forceinline_keyword=$ac_cv_forceinline
|
||||||
|
fi
|
||||||
|
AC_DEFINE_UNQUOTED([FORCEINLINE],$ax_forceinline_keyword,
|
||||||
|
[The most forceful inline keyword known by the compiler])
|
||||||
|
AC_MSG_RESULT($ac_cv_forceinline)
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
])
|
79
m4/ax_gcc_x86_cpuid.m4
Normal file
79
m4/ax_gcc_x86_cpuid.m4
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
# ===========================================================================
|
||||||
|
# http://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# SYNOPSIS
|
||||||
|
#
|
||||||
|
# AX_GCC_X86_CPUID(OP)
|
||||||
|
#
|
||||||
|
# DESCRIPTION
|
||||||
|
#
|
||||||
|
# On Pentium and later x86 processors, with gcc or a compiler that has a
|
||||||
|
# compatible syntax for inline assembly instructions, run a small program
|
||||||
|
# that executes the cpuid instruction with input OP. This can be used to
|
||||||
|
# detect the CPU type.
|
||||||
|
#
|
||||||
|
# On output, the values of the eax, ebx, ecx, and edx registers are stored
|
||||||
|
# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
|
||||||
|
# ax_cv_gcc_x86_cpuid_OP.
|
||||||
|
#
|
||||||
|
# If the cpuid instruction fails (because you are running a
|
||||||
|
# cross-compiler, or because you are not using gcc, or because you are on
|
||||||
|
# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
|
||||||
|
# is set to the string "unknown".
|
||||||
|
#
|
||||||
|
# This macro mainly exists to be used in AX_GCC_ARCHFLAG.
|
||||||
|
#
|
||||||
|
# LICENSE
|
||||||
|
#
|
||||||
|
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||||
|
# Copyright (c) 2008 Matteo Frigo
|
||||||
|
#
|
||||||
|
# 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# As a special exception, the respective Autoconf Macro's copyright owner
|
||||||
|
# gives unlimited permission to copy, distribute and modify the configure
|
||||||
|
# scripts that are the output of Autoconf when processing the Macro. You
|
||||||
|
# need not follow the terms of the GNU General Public License when using
|
||||||
|
# or distributing such scripts, even though portions of the text of the
|
||||||
|
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||||
|
# all other use of the material that constitutes the Autoconf Macro.
|
||||||
|
#
|
||||||
|
# This special exception to the GPL applies to versions of the Autoconf
|
||||||
|
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||||
|
# modified version of the Autoconf Macro, you may extend this special
|
||||||
|
# exception to the GPL to apply to your modified version as well.
|
||||||
|
|
||||||
|
#serial 7
|
||||||
|
|
||||||
|
AC_DEFUN([AX_GCC_X86_CPUID],
|
||||||
|
[AC_REQUIRE([AC_PROG_CC])
|
||||||
|
AC_LANG_PUSH([C])
|
||||||
|
AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
|
||||||
|
[AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
|
||||||
|
int op = $1, eax, ebx, ecx, edx;
|
||||||
|
FILE *f;
|
||||||
|
__asm__("cpuid"
|
||||||
|
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
|
||||||
|
: "a" (op));
|
||||||
|
f = fopen("conftest_cpuid", "w"); if (!f) return 1;
|
||||||
|
fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
])],
|
||||||
|
[ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
|
||||||
|
[ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
|
||||||
|
[ax_cv_gcc_x86_cpuid_$1=unknown])])
|
||||||
|
AC_LANG_POP([C])
|
||||||
|
])
|
7992
m4/libtool.m4
vendored
Normal file
7992
m4/libtool.m4
vendored
Normal file
File diff suppressed because it is too large
Load Diff
384
m4/ltoptions.m4
vendored
Normal file
384
m4/ltoptions.m4
vendored
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
# Helper functions for option handling. -*- Autoconf -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
|
||||||
|
# Inc.
|
||||||
|
# Written by Gary V. Vaughan, 2004
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 7 ltoptions.m4
|
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||||
|
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
|
||||||
|
# ------------------------------------------
|
||||||
|
m4_define([_LT_MANGLE_OPTION],
|
||||||
|
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
|
||||||
|
# ---------------------------------------
|
||||||
|
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
|
||||||
|
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
|
||||||
|
# saved as a flag.
|
||||||
|
m4_define([_LT_SET_OPTION],
|
||||||
|
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
|
||||||
|
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
|
||||||
|
_LT_MANGLE_DEFUN([$1], [$2]),
|
||||||
|
[m4_warning([Unknown $1 option `$2'])])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||||
|
m4_define([_LT_IF_OPTION],
|
||||||
|
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
|
||||||
|
# -------------------------------------------------------
|
||||||
|
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
|
||||||
|
# are set.
|
||||||
|
m4_define([_LT_UNLESS_OPTIONS],
|
||||||
|
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||||
|
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
|
||||||
|
[m4_define([$0_found])])])[]dnl
|
||||||
|
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
|
||||||
|
])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
|
||||||
|
# ----------------------------------------
|
||||||
|
# OPTION-LIST is a space-separated list of Libtool options associated
|
||||||
|
# with MACRO-NAME. If any OPTION has a matching handler declared with
|
||||||
|
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
|
||||||
|
# the unknown option and exit.
|
||||||
|
m4_defun([_LT_SET_OPTIONS],
|
||||||
|
[# Set options
|
||||||
|
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
|
||||||
|
[_LT_SET_OPTION([$1], _LT_Option)])
|
||||||
|
|
||||||
|
m4_if([$1],[LT_INIT],[
|
||||||
|
dnl
|
||||||
|
dnl Simply set some default values (i.e off) if boolean options were not
|
||||||
|
dnl specified:
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
|
||||||
|
])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
|
||||||
|
])
|
||||||
|
dnl
|
||||||
|
dnl If no reference was made to various pairs of opposing options, then
|
||||||
|
dnl we run the default mode handler for the pair. For example, if neither
|
||||||
|
dnl `shared' nor `disable-shared' was passed, we enable building of shared
|
||||||
|
dnl archives by default:
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
|
||||||
|
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
|
||||||
|
[_LT_ENABLE_FAST_INSTALL])
|
||||||
|
])
|
||||||
|
])# _LT_SET_OPTIONS
|
||||||
|
|
||||||
|
|
||||||
|
## --------------------------------- ##
|
||||||
|
## Macros to handle LT_INIT options. ##
|
||||||
|
## --------------------------------- ##
|
||||||
|
|
||||||
|
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
|
||||||
|
# -----------------------------------------
|
||||||
|
m4_define([_LT_MANGLE_DEFUN],
|
||||||
|
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
|
||||||
|
|
||||||
|
|
||||||
|
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
|
||||||
|
# -----------------------------------------------
|
||||||
|
m4_define([LT_OPTION_DEFINE],
|
||||||
|
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
|
||||||
|
])# LT_OPTION_DEFINE
|
||||||
|
|
||||||
|
|
||||||
|
# dlopen
|
||||||
|
# ------
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AC_LIBTOOL_DLOPEN],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [dlopen])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||||
|
put the `dlopen' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
|
||||||
|
|
||||||
|
|
||||||
|
# win32-dll
|
||||||
|
# ---------
|
||||||
|
# Declare package support for building win32 dll's.
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
|
||||||
|
[enable_win32_dll=yes
|
||||||
|
|
||||||
|
case $host in
|
||||||
|
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
|
||||||
|
AC_CHECK_TOOL(AS, as, false)
|
||||||
|
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||||
|
AC_CHECK_TOOL(OBJDUMP, objdump, false)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
test -z "$AS" && AS=as
|
||||||
|
_LT_DECL([], [AS], [1], [Assembler program])dnl
|
||||||
|
|
||||||
|
test -z "$DLLTOOL" && DLLTOOL=dlltool
|
||||||
|
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
|
||||||
|
|
||||||
|
test -z "$OBJDUMP" && OBJDUMP=objdump
|
||||||
|
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
|
||||||
|
])# win32-dll
|
||||||
|
|
||||||
|
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
|
||||||
|
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
|
||||||
|
_LT_SET_OPTION([LT_INIT], [win32-dll])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||||
|
put the `win32-dll' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_SHARED([DEFAULT])
|
||||||
|
# ----------------------------
|
||||||
|
# implement the --enable-shared flag, and supports the `shared' and
|
||||||
|
# `disable-shared' LT_INIT options.
|
||||||
|
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||||
|
m4_define([_LT_ENABLE_SHARED],
|
||||||
|
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||||
|
AC_ARG_ENABLE([shared],
|
||||||
|
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
|
||||||
|
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
|
||||||
|
[p=${PACKAGE-default}
|
||||||
|
case $enableval in
|
||||||
|
yes) enable_shared=yes ;;
|
||||||
|
no) enable_shared=no ;;
|
||||||
|
*)
|
||||||
|
enable_shared=no
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for pkg in $enableval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$pkg" = "X$p"; then
|
||||||
|
enable_shared=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
|
||||||
|
|
||||||
|
_LT_DECL([build_libtool_libs], [enable_shared], [0],
|
||||||
|
[Whether or not to build shared libraries])
|
||||||
|
])# _LT_ENABLE_SHARED
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
|
||||||
|
|
||||||
|
# Old names:
|
||||||
|
AC_DEFUN([AC_ENABLE_SHARED],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AC_DISABLE_SHARED],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-shared])
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
|
||||||
|
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
|
||||||
|
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_STATIC([DEFAULT])
|
||||||
|
# ----------------------------
|
||||||
|
# implement the --enable-static flag, and support the `static' and
|
||||||
|
# `disable-static' LT_INIT options.
|
||||||
|
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||||
|
m4_define([_LT_ENABLE_STATIC],
|
||||||
|
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||||
|
AC_ARG_ENABLE([static],
|
||||||
|
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
|
||||||
|
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
|
||||||
|
[p=${PACKAGE-default}
|
||||||
|
case $enableval in
|
||||||
|
yes) enable_static=yes ;;
|
||||||
|
no) enable_static=no ;;
|
||||||
|
*)
|
||||||
|
enable_static=no
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for pkg in $enableval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$pkg" = "X$p"; then
|
||||||
|
enable_static=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
|
||||||
|
|
||||||
|
_LT_DECL([build_old_libs], [enable_static], [0],
|
||||||
|
[Whether or not to build static libraries])
|
||||||
|
])# _LT_ENABLE_STATIC
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
|
||||||
|
|
||||||
|
# Old names:
|
||||||
|
AC_DEFUN([AC_ENABLE_STATIC],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([AC_DISABLE_STATIC],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-static])
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
|
||||||
|
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
|
||||||
|
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
|
||||||
|
# ----------------------------------
|
||||||
|
# implement the --enable-fast-install flag, and support the `fast-install'
|
||||||
|
# and `disable-fast-install' LT_INIT options.
|
||||||
|
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
|
||||||
|
m4_define([_LT_ENABLE_FAST_INSTALL],
|
||||||
|
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
|
||||||
|
AC_ARG_ENABLE([fast-install],
|
||||||
|
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
|
||||||
|
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
|
||||||
|
[p=${PACKAGE-default}
|
||||||
|
case $enableval in
|
||||||
|
yes) enable_fast_install=yes ;;
|
||||||
|
no) enable_fast_install=no ;;
|
||||||
|
*)
|
||||||
|
enable_fast_install=no
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for pkg in $enableval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$pkg" = "X$p"; then
|
||||||
|
enable_fast_install=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
|
||||||
|
|
||||||
|
_LT_DECL([fast_install], [enable_fast_install], [0],
|
||||||
|
[Whether or not to optimize for fast installation])dnl
|
||||||
|
])# _LT_ENABLE_FAST_INSTALL
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
|
||||||
|
|
||||||
|
# Old names:
|
||||||
|
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||||
|
the `fast-install' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
|
||||||
|
the `disable-fast-install' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
|
||||||
|
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
|
||||||
|
|
||||||
|
|
||||||
|
# _LT_WITH_PIC([MODE])
|
||||||
|
# --------------------
|
||||||
|
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
|
||||||
|
# LT_INIT options.
|
||||||
|
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
|
||||||
|
m4_define([_LT_WITH_PIC],
|
||||||
|
[AC_ARG_WITH([pic],
|
||||||
|
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
|
||||||
|
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
|
||||||
|
[lt_p=${PACKAGE-default}
|
||||||
|
case $withval in
|
||||||
|
yes|no) pic_mode=$withval ;;
|
||||||
|
*)
|
||||||
|
pic_mode=default
|
||||||
|
# Look at the argument we got. We use all the common list separators.
|
||||||
|
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
|
||||||
|
for lt_pkg in $withval; do
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
if test "X$lt_pkg" = "X$lt_p"; then
|
||||||
|
pic_mode=yes
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
IFS="$lt_save_ifs"
|
||||||
|
;;
|
||||||
|
esac],
|
||||||
|
[pic_mode=default])
|
||||||
|
|
||||||
|
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
|
||||||
|
|
||||||
|
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
|
||||||
|
])# _LT_WITH_PIC
|
||||||
|
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
|
||||||
|
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
|
||||||
|
|
||||||
|
# Old name:
|
||||||
|
AU_DEFUN([AC_LIBTOOL_PICMODE],
|
||||||
|
[_LT_SET_OPTION([LT_INIT], [pic-only])
|
||||||
|
AC_DIAGNOSE([obsolete],
|
||||||
|
[$0: Remove this warning and the call to _LT_SET_OPTION when you
|
||||||
|
put the `pic-only' option into LT_INIT's first parameter.])
|
||||||
|
])
|
||||||
|
|
||||||
|
dnl aclocal-1.4 backwards compatibility:
|
||||||
|
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
|
||||||
|
|
||||||
|
## ----------------- ##
|
||||||
|
## LTDL_INIT Options ##
|
||||||
|
## ----------------- ##
|
||||||
|
|
||||||
|
m4_define([_LTDL_MODE], [])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
|
||||||
|
[m4_define([_LTDL_MODE], [nonrecursive])])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
|
||||||
|
[m4_define([_LTDL_MODE], [recursive])])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
|
||||||
|
[m4_define([_LTDL_MODE], [subproject])])
|
||||||
|
|
||||||
|
m4_define([_LTDL_TYPE], [])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [installable],
|
||||||
|
[m4_define([_LTDL_TYPE], [installable])])
|
||||||
|
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||||
|
[m4_define([_LTDL_TYPE], [convenience])])
|
123
m4/ltsugar.m4
vendored
Normal file
123
m4/ltsugar.m4
vendored
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||||
|
# Written by Gary V. Vaughan, 2004
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 6 ltsugar.m4
|
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||||
|
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_join(SEP, ARG1, [ARG2...])
|
||||||
|
# -----------------------------
|
||||||
|
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
|
||||||
|
# associated separator.
|
||||||
|
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
|
||||||
|
# versions in m4sugar had bugs.
|
||||||
|
m4_define([lt_join],
|
||||||
|
[m4_if([$#], [1], [],
|
||||||
|
[$#], [2], [[$2]],
|
||||||
|
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
|
||||||
|
m4_define([_lt_join],
|
||||||
|
[m4_if([$#$2], [2], [],
|
||||||
|
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_car(LIST)
|
||||||
|
# lt_cdr(LIST)
|
||||||
|
# ------------
|
||||||
|
# Manipulate m4 lists.
|
||||||
|
# These macros are necessary as long as will still need to support
|
||||||
|
# Autoconf-2.59 which quotes differently.
|
||||||
|
m4_define([lt_car], [[$1]])
|
||||||
|
m4_define([lt_cdr],
|
||||||
|
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
|
||||||
|
[$#], 1, [],
|
||||||
|
[m4_dquote(m4_shift($@))])])
|
||||||
|
m4_define([lt_unquote], $1)
|
||||||
|
|
||||||
|
|
||||||
|
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
|
||||||
|
# ------------------------------------------
|
||||||
|
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
|
||||||
|
# Note that neither SEPARATOR nor STRING are expanded; they are appended
|
||||||
|
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
|
||||||
|
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
|
||||||
|
# than defined and empty).
|
||||||
|
#
|
||||||
|
# This macro is needed until we can rely on Autoconf 2.62, since earlier
|
||||||
|
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
|
||||||
|
m4_define([lt_append],
|
||||||
|
[m4_define([$1],
|
||||||
|
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
|
||||||
|
# ----------------------------------------------------------
|
||||||
|
# Produce a SEP delimited list of all paired combinations of elements of
|
||||||
|
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
|
||||||
|
# has the form PREFIXmINFIXSUFFIXn.
|
||||||
|
# Needed until we can rely on m4_combine added in Autoconf 2.62.
|
||||||
|
m4_define([lt_combine],
|
||||||
|
[m4_if(m4_eval([$# > 3]), [1],
|
||||||
|
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
|
||||||
|
[[m4_foreach([_Lt_prefix], [$2],
|
||||||
|
[m4_foreach([_Lt_suffix],
|
||||||
|
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
|
||||||
|
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
|
||||||
|
# -----------------------------------------------------------------------
|
||||||
|
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
|
||||||
|
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
|
||||||
|
m4_define([lt_if_append_uniq],
|
||||||
|
[m4_ifdef([$1],
|
||||||
|
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
|
||||||
|
[lt_append([$1], [$2], [$3])$4],
|
||||||
|
[$5])],
|
||||||
|
[lt_append([$1], [$2], [$3])$4])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_add(DICT, KEY, VALUE)
|
||||||
|
# -----------------------------
|
||||||
|
m4_define([lt_dict_add],
|
||||||
|
[m4_define([$1($2)], [$3])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
|
||||||
|
# --------------------------------------------
|
||||||
|
m4_define([lt_dict_add_subkey],
|
||||||
|
[m4_define([$1($2:$3)], [$4])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_fetch(DICT, KEY, [SUBKEY])
|
||||||
|
# ----------------------------------
|
||||||
|
m4_define([lt_dict_fetch],
|
||||||
|
[m4_ifval([$3],
|
||||||
|
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
|
||||||
|
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
|
||||||
|
# -----------------------------------------------------------------
|
||||||
|
m4_define([lt_if_dict_fetch],
|
||||||
|
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
|
||||||
|
[$5],
|
||||||
|
[$6])])
|
||||||
|
|
||||||
|
|
||||||
|
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
m4_define([lt_dict_filter],
|
||||||
|
[m4_if([$5], [], [],
|
||||||
|
[lt_join(m4_quote(m4_default([$4], [[, ]])),
|
||||||
|
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
|
||||||
|
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
|
||||||
|
])
|
23
m4/ltversion.m4
vendored
Normal file
23
m4/ltversion.m4
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
# Written by Scott James Remnant, 2004
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# serial 3337 ltversion.m4
|
||||||
|
# This file is part of GNU Libtool
|
||||||
|
|
||||||
|
m4_define([LT_PACKAGE_VERSION], [2.4.2])
|
||||||
|
m4_define([LT_PACKAGE_REVISION], [1.3337])
|
||||||
|
|
||||||
|
AC_DEFUN([LTVERSION_VERSION],
|
||||||
|
[macro_version='2.4.2'
|
||||||
|
macro_revision='1.3337'
|
||||||
|
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||||
|
_LT_DECL(, macro_revision, 0)
|
||||||
|
])
|
98
m4/lt~obsolete.m4
vendored
Normal file
98
m4/lt~obsolete.m4
vendored
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
|
||||||
|
# Written by Scott James Remnant, 2004.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation gives
|
||||||
|
# unlimited permission to copy and/or distribute it, with or without
|
||||||
|
# modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 5 lt~obsolete.m4
|
||||||
|
|
||||||
|
# These exist entirely to fool aclocal when bootstrapping libtool.
|
||||||
|
#
|
||||||
|
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
|
||||||
|
# which have later been changed to m4_define as they aren't part of the
|
||||||
|
# exported API, or moved to Autoconf or Automake where they belong.
|
||||||
|
#
|
||||||
|
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
|
||||||
|
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
|
||||||
|
# using a macro with the same name in our local m4/libtool.m4 it'll
|
||||||
|
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
|
||||||
|
# and doesn't know about Autoconf macros at all.)
|
||||||
|
#
|
||||||
|
# So we provide this file, which has a silly filename so it's always
|
||||||
|
# included after everything else. This provides aclocal with the
|
||||||
|
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
|
||||||
|
# because those macros already exist, or will be overwritten later.
|
||||||
|
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
|
||||||
|
#
|
||||||
|
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
|
||||||
|
# Yes, that means every name once taken will need to remain here until
|
||||||
|
# we give up compatibility with versions before 1.7, at which point
|
||||||
|
# we need to keep only those names which we still refer to.
|
||||||
|
|
||||||
|
# This is to help aclocal find these macros, as it can't see m4_define.
|
||||||
|
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
|
||||||
|
|
||||||
|
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
|
||||||
|
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
|
||||||
|
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
|
||||||
|
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
|
||||||
|
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
|
||||||
|
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
|
||||||
|
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
|
||||||
|
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
|
||||||
|
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
|
||||||
|
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
|
||||||
|
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
|
||||||
|
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
|
||||||
|
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
|
||||||
|
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
|
||||||
|
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
|
||||||
|
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
|
||||||
|
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
|
||||||
|
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
|
||||||
|
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
|
||||||
|
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
|
||||||
|
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
|
||||||
|
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
|
||||||
|
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
|
||||||
|
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
|
||||||
|
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
|
||||||
|
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
|
||||||
|
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
|
||||||
|
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
|
||||||
|
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
|
||||||
|
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
|
||||||
|
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
|
||||||
|
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
|
||||||
|
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||||
|
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||||
|
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
152
src/Makefile.am
Normal file
152
src/Makefile.am
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
# BLAKE2 reference source code package - optimized 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/>.
|
||||||
|
|
||||||
|
EXTRA_DIST =
|
||||||
|
|
||||||
|
CPPFLAGS += $(LTDLINCL) $(OPENMP_CFLAGS)
|
||||||
|
CFLAGS += $(OPENMP_CFLAGS)
|
||||||
|
LDFLAGS += -version-info $(B2_LIBRARY_VERSION)
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libb2.la
|
||||||
|
libb2_la_LIBADD = # -lgomp -lpthread
|
||||||
|
libb2_la_CPPFLAGS = -DSUFFIX= \
|
||||||
|
$(LTDLINCL) \
|
||||||
|
${top_builddir}/src/
|
||||||
|
|
||||||
|
include_HEADERS = blake2.h
|
||||||
|
|
||||||
|
if USE_FAT
|
||||||
|
noinst_LTLIBRARIES = libblake2b_ref.la \
|
||||||
|
libblake2b_sse2.la \
|
||||||
|
libblake2b_ssse3.la \
|
||||||
|
libblake2b_sse41.la \
|
||||||
|
libblake2b_avx.la \
|
||||||
|
libblake2b_xop.la \
|
||||||
|
libblake2s_ref.la \
|
||||||
|
libblake2s_sse2.la \
|
||||||
|
libblake2s_ssse3.la \
|
||||||
|
libblake2s_sse41.la \
|
||||||
|
libblake2s_avx.la \
|
||||||
|
libblake2s_xop.la
|
||||||
|
|
||||||
|
libb2_la_SOURCES = blake2-dispatch.c blake2sp.c blake2bp.c
|
||||||
|
libb2_la_LIBADD += libblake2b_ref.la \
|
||||||
|
libblake2b_sse2.la \
|
||||||
|
libblake2b_ssse3.la \
|
||||||
|
libblake2b_sse41.la \
|
||||||
|
libblake2b_avx.la \
|
||||||
|
libblake2b_xop.la \
|
||||||
|
libblake2s_ref.la \
|
||||||
|
libblake2s_sse2.la \
|
||||||
|
libblake2s_ssse3.la \
|
||||||
|
libblake2s_sse41.la \
|
||||||
|
libblake2s_avx.la \
|
||||||
|
libblake2s_xop.la
|
||||||
|
|
||||||
|
|
||||||
|
libblake2b_ref_la_SOURCES = blake2b-ref.c
|
||||||
|
libblake2b_ref_la_CPPFLAGS = -DSUFFIX=_ref
|
||||||
|
libblake2b_ref_la_CFLAGS =
|
||||||
|
|
||||||
|
libblake2b_sse2_la_SOURCES = blake2b.c
|
||||||
|
libblake2b_sse2_la_CPPFLAGS = -DSUFFIX=_sse2
|
||||||
|
libblake2b_sse2_la_CFLAGS = -msse2
|
||||||
|
|
||||||
|
libblake2b_ssse3_la_SOURCES = blake2b.c
|
||||||
|
libblake2b_ssse3_la_CPPFLAGS = -DSUFFIX=_ssse3
|
||||||
|
libblake2b_ssse3_la_CFLAGS = -msse2 -mssse3
|
||||||
|
|
||||||
|
libblake2b_sse41_la_SOURCES = blake2b.c
|
||||||
|
libblake2b_sse41_la_CPPFLAGS = -DSUFFIX=_sse41
|
||||||
|
libblake2b_sse41_la_CFLAGS = -msse2 -mssse3 -msse4.1
|
||||||
|
|
||||||
|
libblake2b_avx_la_SOURCES = blake2b.c
|
||||||
|
libblake2b_avx_la_CPPFLAGS = -DSUFFIX=_avx
|
||||||
|
libblake2b_avx_la_CFLAGS = -msse2 -mssse3 -msse4.1 -mavx
|
||||||
|
|
||||||
|
libblake2b_xop_la_SOURCES = blake2b.c
|
||||||
|
libblake2b_xop_la_CPPFLAGS = -DSUFFIX=_xop
|
||||||
|
libblake2b_xop_la_CFLAGS = -msse2 -mssse3 -msse4.1 -mavx -mxop
|
||||||
|
|
||||||
|
|
||||||
|
libblake2s_ref_la_SOURCES = blake2s-ref.c
|
||||||
|
libblake2s_ref_la_CPPFLAGS = -DSUFFIX=_ref
|
||||||
|
libblake2s_ref_la_CFLAGS =
|
||||||
|
|
||||||
|
libblake2s_sse2_la_SOURCES = blake2s.c
|
||||||
|
libblake2s_sse2_la_CPPFLAGS = -DSUFFIX=_sse2
|
||||||
|
libblake2s_sse2_la_CFLAGS = -msse2
|
||||||
|
|
||||||
|
libblake2s_ssse3_la_SOURCES = blake2s.c
|
||||||
|
libblake2s_ssse3_la_CPPFLAGS = -DSUFFIX=_ssse3
|
||||||
|
libblake2s_ssse3_la_CFLAGS = -msse2 -mssse3
|
||||||
|
|
||||||
|
libblake2s_sse41_la_SOURCES = blake2s.c
|
||||||
|
libblake2s_sse41_la_CPPFLAGS = -DSUFFIX=_sse41
|
||||||
|
libblake2s_sse41_la_CFLAGS = -msse2 -mssse3 -msse4.1
|
||||||
|
|
||||||
|
libblake2s_avx_la_SOURCES = blake2s.c
|
||||||
|
libblake2s_avx_la_CPPFLAGS = -DSUFFIX=_avx
|
||||||
|
libblake2s_avx_la_CFLAGS = -msse2 -mssse3 -msse4.1 -mavx
|
||||||
|
|
||||||
|
libblake2s_xop_la_SOURCES = blake2s.c
|
||||||
|
libblake2s_xop_la_CPPFLAGS = -DSUFFIX=_xop
|
||||||
|
libblake2s_xop_la_CFLAGS = -msse2 -mssse3 -msse4.1 -mavx -mxop
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if USE_SSE
|
||||||
|
libb2_la_SOURCES = blake2sp.c \
|
||||||
|
blake2bp.c \
|
||||||
|
blake2s.c \
|
||||||
|
blake2b.c \
|
||||||
|
blake2-impl.h \
|
||||||
|
blake2-config.h \
|
||||||
|
blake2s-round.h \
|
||||||
|
blake2b-round.h \
|
||||||
|
blake2s-load-xop.h \
|
||||||
|
blake2s-load-sse41.h \
|
||||||
|
blake2s-load-sse2.h \
|
||||||
|
blake2b-load-sse41.h \
|
||||||
|
blake2b-load-sse2.h
|
||||||
|
else
|
||||||
|
libb2_la_SOURCES = blake2s-ref.c \
|
||||||
|
blake2b-ref.c \
|
||||||
|
blake2.h \
|
||||||
|
blake2-impl.h \
|
||||||
|
blake2sp.c \
|
||||||
|
blake2bp.c \
|
||||||
|
blake2-kat.h
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
TESTS_TARGETS = blake2s-test \
|
||||||
|
blake2b-test \
|
||||||
|
blake2sp-test \
|
||||||
|
blake2bp-test
|
||||||
|
|
||||||
|
check_PROGRAMS = $(TESTS_TARGETS)
|
||||||
|
TESTS = $(TESTS_TARGETS)
|
||||||
|
|
||||||
|
TESTS_LDADD = ${top_builddir}/src/libb2.la
|
||||||
|
|
||||||
|
blake2s_test_SOURCE = blake2s-test.c blake2-kat.h
|
||||||
|
blake2s_test_LDADD = $(TESTS_LDADD)
|
||||||
|
|
||||||
|
blake2b_test_SOURCE = blake2b-test.c blake2-kat.h
|
||||||
|
blake2b_test_LDADD = $(TESTS_LDADD)
|
||||||
|
|
||||||
|
blake2sp_test_SOURCE = blake2sp-test.c blake2-kat.h
|
||||||
|
blake2sp_test_LDADD = $(TESTS_LDADD)
|
||||||
|
|
||||||
|
blake2bp_test_SOURCE = blake2bp-test.c blake2-kat.h
|
||||||
|
blake2bp_test_LDADD = $(TESTS_LDADD)
|
||||||
|
|
71
src/blake2-config.h
Normal file
71
src/blake2-config.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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_CONFIG_H__
|
||||||
|
#define __BLAKE2_CONFIG_H__
|
||||||
|
|
||||||
|
#if defined(__SSE2__)
|
||||||
|
#define HAVE_SSE2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSSE3__)
|
||||||
|
#define HAVE_SSSE3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SSE4_1__)
|
||||||
|
#define HAVE_SSE4_1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__AVX__)
|
||||||
|
#define HAVE_AVX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__XOP__)
|
||||||
|
#define HAVE_XOP
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_AVX2
|
||||||
|
#ifndef HAVE_AVX
|
||||||
|
#define HAVE_AVX
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_XOP
|
||||||
|
#ifndef HAVE_AVX
|
||||||
|
#define HAVE_AVX
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_AVX
|
||||||
|
#ifndef HAVE_SSE4_1
|
||||||
|
#define HAVE_SSE4_1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SSE41
|
||||||
|
#ifndef HAVE_SSSE3
|
||||||
|
#define HAVE_SSSE3
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SSSE3
|
||||||
|
#define HAVE_SSE2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(HAVE_SSE2)
|
||||||
|
#error "This code requires at least SSE2."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
560
src/blake2-dispatch.c
Normal file
560
src/blake2-dispatch.c
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdio.h>
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#include "blake2.h"
|
||||||
|
|
||||||
|
#if defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || defined(_M_X64)
|
||||||
|
#define HAVE_X86
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
SSE2 = 1,
|
||||||
|
SSSE3 = 2,
|
||||||
|
SSE41 = 3,
|
||||||
|
AVX = 4,
|
||||||
|
XOP = 5,
|
||||||
|
/* AVX2 = 6, */
|
||||||
|
#endif
|
||||||
|
} cpu_feature_t;
|
||||||
|
|
||||||
|
static const char feature_names[][8] =
|
||||||
|
{
|
||||||
|
"none",
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
"sse2",
|
||||||
|
"ssse3",
|
||||||
|
"sse41",
|
||||||
|
"avx",
|
||||||
|
"xop",
|
||||||
|
/* "avx2" */
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx )
|
||||||
|
{
|
||||||
|
__asm__ __volatile__(
|
||||||
|
#if defined(__i386__) /* This is needed for -fPIC to work on i386 */
|
||||||
|
"movl %%ebx, %%esi\n\t"
|
||||||
|
#endif
|
||||||
|
"cpuid\n\t"
|
||||||
|
#if defined(__i386__)
|
||||||
|
"xchgl %%ebx, %%esi\n\t"
|
||||||
|
: "=a"( *eax ), "=S"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) );
|
||||||
|
#else
|
||||||
|
: "=a"( *eax ), "=b"( *ebx ), "=c"( *ecx ), "=d"( *edx ) : "a"( *eax ) );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#include <intrin.h>
|
||||||
|
static inline void cpuid( uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx )
|
||||||
|
{
|
||||||
|
int regs[4];
|
||||||
|
__cpuid( regs, *eax );
|
||||||
|
*eax = regs[0];
|
||||||
|
*ebx = regs[1];
|
||||||
|
*ecx = regs[2];
|
||||||
|
*edx = regs[3];
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error "Don't know how to call cpuid on this compiler!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_X86 */
|
||||||
|
|
||||||
|
static inline cpu_feature_t get_cpu_features( void )
|
||||||
|
{
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
static volatile int initialized = 0;
|
||||||
|
static cpu_feature_t feature = NONE; // Safe default
|
||||||
|
uint32_t eax, ecx, edx, ebx;
|
||||||
|
|
||||||
|
if( initialized )
|
||||||
|
return feature;
|
||||||
|
|
||||||
|
eax = 1;
|
||||||
|
cpuid( &eax, &ebx, &ecx, &edx );
|
||||||
|
|
||||||
|
if( 1 & ( edx >> 26 ) )
|
||||||
|
feature = SSE2;
|
||||||
|
|
||||||
|
if( 1 & ( ecx >> 9 ) )
|
||||||
|
feature = SSSE3;
|
||||||
|
|
||||||
|
if( 1 & ( ecx >> 19 ) )
|
||||||
|
feature = SSE41;
|
||||||
|
|
||||||
|
#if defined(WIN32) /* Work around the fact that Windows <7 does NOT support AVX... */
|
||||||
|
if( IsProcessorFeaturePresent(17) ) /* Some environments don't know about PF_XSAVE_ENABLED */
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if( 1 & ( ecx >> 28 ) )
|
||||||
|
feature = AVX;
|
||||||
|
|
||||||
|
|
||||||
|
eax = 0x80000001;
|
||||||
|
cpuid( &eax, &ebx, &ecx, &edx );
|
||||||
|
|
||||||
|
if( 1 & ( ecx >> 11 ) )
|
||||||
|
feature = XOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For future architectures */
|
||||||
|
/*
|
||||||
|
eax = 7; ecx = 0;
|
||||||
|
cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
|
||||||
|
if(1&(ebx >> 5))
|
||||||
|
feature = AVX2;
|
||||||
|
*/
|
||||||
|
/* fprintf( stderr, "Using %s engine\n", feature_names[feature] ); */
|
||||||
|
initialized = 1;
|
||||||
|
return feature;
|
||||||
|
#else
|
||||||
|
return NONE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int blake2b_init_ref( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_ref( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_ref( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_ref( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_ref( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
|
||||||
|
int blake2b_init_sse2( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_sse2( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_sse2( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_sse2( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_sse2( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2b_init_ssse3( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_ssse3( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_ssse3( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_ssse3( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_ssse3( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2b_init_sse41( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_sse41( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_sse41( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_sse41( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_sse41( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2b_init_avx( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_avx( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_avx( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_avx( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_avx( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2b_init_xop( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_xop( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_xop( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_xop( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_xop( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
#endif /* HAVE_X86 */
|
||||||
|
|
||||||
|
int blake2s_init_ref( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_ref( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_ref( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_ref( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_ref( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_ref( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
|
||||||
|
int blake2s_init_sse2( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_sse2( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_sse2( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_sse2( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_sse2( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_sse2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2s_init_ssse3( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_ssse3( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_ssse3( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_ssse3( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_ssse3( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_ssse3( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2s_init_sse41( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_sse41( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_sse41( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_sse41( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_sse41( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_sse41( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2s_init_avx( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_avx( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_avx( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_avx( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_avx( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_avx( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2s_init_xop( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_xop( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_xop( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_xop( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_xop( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_xop( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
#endif /* HAVE_X86 */
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef int ( *blake2b_init_fn )( blake2b_state *, size_t );
|
||||||
|
typedef int ( *blake2b_init_key_fn )( blake2b_state *, size_t, const void *, size_t );
|
||||||
|
typedef int ( *blake2b_init_param_fn )( blake2b_state *, const blake2b_param * );
|
||||||
|
typedef int ( *blake2b_update_fn )( blake2b_state *, const uint8_t *, size_t );
|
||||||
|
typedef int ( *blake2b_final_fn )( blake2b_state *, uint8_t *, size_t );
|
||||||
|
typedef int ( *blake2b_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t );
|
||||||
|
|
||||||
|
typedef int ( *blake2s_init_fn )( blake2s_state *, size_t );
|
||||||
|
typedef int ( *blake2s_init_key_fn )( blake2s_state *, size_t, const void *, size_t );
|
||||||
|
typedef int ( *blake2s_init_param_fn )( blake2s_state *, const blake2s_param * );
|
||||||
|
typedef int ( *blake2s_update_fn )( blake2s_state *, const uint8_t *, size_t );
|
||||||
|
typedef int ( *blake2s_final_fn )( blake2s_state *, uint8_t *, size_t );
|
||||||
|
typedef int ( *blake2s_fn )( uint8_t *, const void *, const void *, size_t, size_t, size_t );
|
||||||
|
|
||||||
|
static const blake2b_init_fn blake2b_init_table[] =
|
||||||
|
{
|
||||||
|
blake2b_init_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2b_init_sse2,
|
||||||
|
blake2b_init_ssse3,
|
||||||
|
blake2b_init_sse41,
|
||||||
|
blake2b_init_avx,
|
||||||
|
blake2b_init_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2b_init_key_fn blake2b_init_key_table[] =
|
||||||
|
{
|
||||||
|
blake2b_init_key_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2b_init_key_sse2,
|
||||||
|
blake2b_init_key_ssse3,
|
||||||
|
blake2b_init_key_sse41,
|
||||||
|
blake2b_init_key_avx,
|
||||||
|
blake2b_init_key_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2b_init_param_fn blake2b_init_param_table[] =
|
||||||
|
{
|
||||||
|
blake2b_init_param_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2b_init_param_sse2,
|
||||||
|
blake2b_init_param_ssse3,
|
||||||
|
blake2b_init_param_sse41,
|
||||||
|
blake2b_init_param_avx,
|
||||||
|
blake2b_init_param_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2b_update_fn blake2b_update_table[] =
|
||||||
|
{
|
||||||
|
blake2b_update_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2b_update_sse2,
|
||||||
|
blake2b_update_ssse3,
|
||||||
|
blake2b_update_sse41,
|
||||||
|
blake2b_update_avx,
|
||||||
|
blake2b_update_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2b_final_fn blake2b_final_table[] =
|
||||||
|
{
|
||||||
|
blake2b_final_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2b_final_sse2,
|
||||||
|
blake2b_final_ssse3,
|
||||||
|
blake2b_final_sse41,
|
||||||
|
blake2b_final_avx,
|
||||||
|
blake2b_final_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2b_fn blake2b_table[] =
|
||||||
|
{
|
||||||
|
blake2b_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2b_sse2,
|
||||||
|
blake2b_ssse3,
|
||||||
|
blake2b_sse41,
|
||||||
|
blake2b_avx,
|
||||||
|
blake2b_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2s_init_fn blake2s_init_table[] =
|
||||||
|
{
|
||||||
|
blake2s_init_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2s_init_sse2,
|
||||||
|
blake2s_init_ssse3,
|
||||||
|
blake2s_init_sse41,
|
||||||
|
blake2s_init_avx,
|
||||||
|
blake2s_init_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2s_init_key_fn blake2s_init_key_table[] =
|
||||||
|
{
|
||||||
|
blake2s_init_key_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2s_init_key_sse2,
|
||||||
|
blake2s_init_key_ssse3,
|
||||||
|
blake2s_init_key_sse41,
|
||||||
|
blake2s_init_key_avx,
|
||||||
|
blake2s_init_key_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2s_init_param_fn blake2s_init_param_table[] =
|
||||||
|
{
|
||||||
|
blake2s_init_param_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2s_init_param_sse2,
|
||||||
|
blake2s_init_param_ssse3,
|
||||||
|
blake2s_init_param_sse41,
|
||||||
|
blake2s_init_param_avx,
|
||||||
|
blake2s_init_param_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2s_update_fn blake2s_update_table[] =
|
||||||
|
{
|
||||||
|
blake2s_update_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2s_update_sse2,
|
||||||
|
blake2s_update_ssse3,
|
||||||
|
blake2s_update_sse41,
|
||||||
|
blake2s_update_avx,
|
||||||
|
blake2s_update_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2s_final_fn blake2s_final_table[] =
|
||||||
|
{
|
||||||
|
blake2s_final_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2s_final_sse2,
|
||||||
|
blake2s_final_ssse3,
|
||||||
|
blake2s_final_sse41,
|
||||||
|
blake2s_final_avx,
|
||||||
|
blake2s_final_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const blake2s_fn blake2s_table[] =
|
||||||
|
{
|
||||||
|
blake2s_ref,
|
||||||
|
#if defined(HAVE_X86)
|
||||||
|
blake2s_sse2,
|
||||||
|
blake2s_ssse3,
|
||||||
|
blake2s_sse41,
|
||||||
|
blake2s_avx,
|
||||||
|
blake2s_xop
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int blake2b_init_dispatch( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
int blake2s_init_dispatch( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static blake2b_init_fn blake2b_init_ptr = blake2b_init_dispatch;
|
||||||
|
static blake2b_init_key_fn blake2b_init_key_ptr = blake2b_init_key_dispatch;
|
||||||
|
static blake2b_init_param_fn blake2b_init_param_ptr = blake2b_init_param_dispatch;
|
||||||
|
static blake2b_update_fn blake2b_update_ptr = blake2b_update_dispatch;
|
||||||
|
static blake2b_final_fn blake2b_final_ptr = blake2b_final_dispatch;
|
||||||
|
static blake2b_fn blake2b_ptr = blake2b_dispatch;
|
||||||
|
|
||||||
|
static blake2s_init_fn blake2s_init_ptr = blake2s_init_dispatch;
|
||||||
|
static blake2s_init_key_fn blake2s_init_key_ptr = blake2s_init_key_dispatch;
|
||||||
|
static blake2s_init_param_fn blake2s_init_param_ptr = blake2s_init_param_dispatch;
|
||||||
|
static blake2s_update_fn blake2s_update_ptr = blake2s_update_dispatch;
|
||||||
|
static blake2s_final_fn blake2s_final_ptr = blake2s_final_dispatch;
|
||||||
|
static blake2s_fn blake2s_ptr = blake2s_dispatch;
|
||||||
|
|
||||||
|
int blake2b_init_dispatch( blake2b_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
blake2b_init_ptr = blake2b_init_table[get_cpu_features()];
|
||||||
|
return blake2b_init_ptr( S, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_init_key_dispatch( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_init_key_ptr = blake2b_init_key_table[get_cpu_features()];
|
||||||
|
return blake2b_init_key_ptr( S, outlen, key, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_init_param_dispatch( blake2b_state *S, const blake2b_param *P )
|
||||||
|
{
|
||||||
|
blake2b_init_param_ptr = blake2b_init_param_table[get_cpu_features()];
|
||||||
|
return blake2b_init_param_ptr( S, P );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_update_dispatch( blake2b_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
blake2b_update_ptr = blake2b_update_table[get_cpu_features()];
|
||||||
|
return blake2b_update_ptr( S, in, inlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_final_dispatch( blake2b_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
blake2b_final_ptr = blake2b_final_table[get_cpu_features()];
|
||||||
|
return blake2b_final_ptr( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_ptr = blake2b_table[get_cpu_features()];
|
||||||
|
return blake2b_ptr( out, in, key, outlen, inlen, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b_init( blake2b_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
return blake2b_init_ptr( S, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
return blake2b_init_key_ptr( S, outlen, key, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||||
|
{
|
||||||
|
return blake2b_init_param_ptr( S, P );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
return blake2b_update_ptr( S, in, inlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
return blake2b_final_ptr( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
return blake2b_ptr( out, in, key, outlen, inlen, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_init_dispatch( blake2s_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
blake2s_init_ptr = blake2s_init_table[get_cpu_features()];
|
||||||
|
return blake2s_init_ptr( S, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_init_key_dispatch( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2s_init_key_ptr = blake2s_init_key_table[get_cpu_features()];
|
||||||
|
return blake2s_init_key_ptr( S, outlen, key, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_init_param_dispatch( blake2s_state *S, const blake2s_param *P )
|
||||||
|
{
|
||||||
|
blake2s_init_param_ptr = blake2s_init_param_table[get_cpu_features()];
|
||||||
|
return blake2s_init_param_ptr( S, P );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_update_dispatch( blake2s_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
blake2s_update_ptr = blake2s_update_table[get_cpu_features()];
|
||||||
|
return blake2s_update_ptr( S, in, inlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_final_dispatch( blake2s_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
blake2s_final_ptr = blake2s_final_table[get_cpu_features()];
|
||||||
|
return blake2s_final_ptr( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_dispatch( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2s_ptr = blake2s_table[get_cpu_features()];
|
||||||
|
return blake2s_ptr( out, in, key, outlen, inlen, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2s_init( blake2s_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
return blake2s_init_ptr( S, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
return blake2s_init_key_ptr( S, outlen, key, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||||
|
{
|
||||||
|
return blake2s_init_param_ptr( S, P );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
return blake2s_update_ptr( S, in, inlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
return blake2s_final_ptr( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
return blake2s_ptr( out, in, key, outlen, inlen, keylen );
|
||||||
|
}
|
||||||
|
|
139
src/blake2-impl.h
Normal file
139
src/blake2-impl.h
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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_IMPL_H__
|
||||||
|
#define __BLAKE2_IMPL_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#define BLAKE2_IMPL_CAT(x,y) x ## y
|
||||||
|
#define BLAKE2_IMPL_EVAL(x,y) BLAKE2_IMPL_CAT(x,y)
|
||||||
|
#define BLAKE2_IMPL_NAME(fun) BLAKE2_IMPL_EVAL(fun, SUFFIX)
|
||||||
|
|
||||||
|
static inline uint32_t load32( const void *src )
|
||||||
|
{
|
||||||
|
#if defined(NATIVE_LITTLE_ENDIAN) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
|
||||||
|
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) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
|
||||||
|
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) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
|
||||||
|
*( 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) && !defined(HAVE_ALIGNED_ACCESS_REQUIRED)
|
||||||
|
*( 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
16467
src/blake2-kat.h
Normal file
16467
src/blake2-kat.h
Normal file
File diff suppressed because it is too large
Load Diff
168
src/blake2.h
Normal file
168
src/blake2.h
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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)
|
||||||
|
#if defined(DYNAMIC_LIB)
|
||||||
|
#if defined(DYNAMIC_LIB_EXPORT)
|
||||||
|
#define EXPORT_DLL __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define EXPORT_DLL __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define EXPORT_DLL
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define EXPORT_DLL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum blake2s_constant
|
||||||
|
{
|
||||||
|
BLAKE2S_BLOCKBYTES = 64,
|
||||||
|
BLAKE2S_OUTBYTES = 32,
|
||||||
|
BLAKE2S_KEYBYTES = 32,
|
||||||
|
BLAKE2S_SALTBYTES = 8,
|
||||||
|
BLAKE2S_PERSONALBYTES = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
enum blake2b_constant
|
||||||
|
{
|
||||||
|
BLAKE2B_BLOCKBYTES = 128,
|
||||||
|
BLAKE2B_OUTBYTES = 64,
|
||||||
|
BLAKE2B_KEYBYTES = 64,
|
||||||
|
BLAKE2B_SALTBYTES = 16,
|
||||||
|
BLAKE2B_PERSONALBYTES = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct __blake2s_param
|
||||||
|
{
|
||||||
|
uint8_t digest_length; // 1
|
||||||
|
uint8_t key_length; // 2
|
||||||
|
uint8_t fanout; // 3
|
||||||
|
uint8_t depth; // 4
|
||||||
|
uint32_t leaf_length; // 8
|
||||||
|
uint8_t node_offset[6];// 14
|
||||||
|
uint8_t node_depth; // 15
|
||||||
|
uint8_t inner_length; // 16
|
||||||
|
// uint8_t reserved[0];
|
||||||
|
uint8_t salt[BLAKE2S_SALTBYTES]; // 24
|
||||||
|
uint8_t personal[BLAKE2S_PERSONALBYTES]; // 32
|
||||||
|
} blake2s_param;
|
||||||
|
|
||||||
|
typedef struct __blake2s_state
|
||||||
|
{
|
||||||
|
uint32_t h[8];
|
||||||
|
uint32_t t[2];
|
||||||
|
uint32_t f[2];
|
||||||
|
uint8_t buf[2 * BLAKE2S_BLOCKBYTES];
|
||||||
|
uint32_t buflen;
|
||||||
|
uint8_t outlen;
|
||||||
|
uint8_t last_node;
|
||||||
|
} blake2s_state;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
typedef struct __blake2b_state
|
||||||
|
{
|
||||||
|
uint64_t h[8];
|
||||||
|
uint64_t t[2];
|
||||||
|
uint64_t f[2];
|
||||||
|
uint8_t buf[2 * BLAKE2B_BLOCKBYTES];
|
||||||
|
uint32_t buflen;
|
||||||
|
uint8_t outlen;
|
||||||
|
uint8_t last_node;
|
||||||
|
} blake2b_state;
|
||||||
|
|
||||||
|
typedef struct __blake2sp_state
|
||||||
|
{
|
||||||
|
blake2s_state S[8][1];
|
||||||
|
blake2s_state R[1];
|
||||||
|
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
|
||||||
|
uint32_t buflen;
|
||||||
|
uint8_t outlen;
|
||||||
|
} blake2sp_state;
|
||||||
|
|
||||||
|
typedef struct __blake2bp_state
|
||||||
|
{
|
||||||
|
blake2b_state S[4][1];
|
||||||
|
blake2b_state R[1];
|
||||||
|
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
|
||||||
|
uint32_t buflen;
|
||||||
|
uint8_t outlen;
|
||||||
|
} blake2bp_state;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
// Streaming API
|
||||||
|
EXPORT_DLL int blake2s_init( blake2s_state *S, size_t outlen );
|
||||||
|
EXPORT_DLL int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
EXPORT_DLL int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||||
|
EXPORT_DLL int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
EXPORT_DLL int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2b_init( blake2b_state *S, size_t outlen );
|
||||||
|
EXPORT_DLL int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
EXPORT_DLL int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||||
|
EXPORT_DLL int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
EXPORT_DLL int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2sp_init( blake2sp_state *S, size_t outlen );
|
||||||
|
EXPORT_DLL int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
EXPORT_DLL int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
EXPORT_DLL int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen );
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2bp_init( blake2bp_state *S, size_t outlen );
|
||||||
|
EXPORT_DLL int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
EXPORT_DLL int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
EXPORT_DLL int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen );
|
||||||
|
|
||||||
|
// Simple API
|
||||||
|
EXPORT_DLL int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
EXPORT_DLL int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
EXPORT_DLL int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
EXPORT_DLL int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
|
||||||
|
static inline int blake2( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
return blake2b( out, in, key, outlen, inlen, keylen );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
68
src/blake2b-load-sse2.h
Normal file
68
src/blake2b-load-sse2.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2B_LOAD_SSE2_H__
|
||||||
|
#define __BLAKE2B_LOAD_SSE2_H__
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
|
||||||
|
#define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
|
||||||
|
#define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
|
||||||
|
#define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
|
||||||
|
#define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
|
||||||
|
#define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
|
||||||
|
#define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
|
||||||
|
#define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
|
||||||
|
#define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5)
|
||||||
|
#define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2)
|
||||||
|
#define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7)
|
||||||
|
#define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1)
|
||||||
|
#define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13)
|
||||||
|
#define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12)
|
||||||
|
#define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4)
|
||||||
|
#define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0)
|
||||||
|
#define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2)
|
||||||
|
#define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4)
|
||||||
|
#define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6)
|
||||||
|
#define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8)
|
||||||
|
#define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0)
|
||||||
|
#define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11)
|
||||||
|
#define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15)
|
||||||
|
#define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14)
|
||||||
|
#define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14)
|
||||||
|
#define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13)
|
||||||
|
#define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9)
|
||||||
|
#define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2)
|
||||||
|
#define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12)
|
||||||
|
#define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1)
|
||||||
|
#define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8)
|
||||||
|
#define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6)
|
||||||
|
#define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11)
|
||||||
|
#define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3)
|
||||||
|
#define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1)
|
||||||
|
#define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4)
|
||||||
|
#define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7)
|
||||||
|
#define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6)
|
||||||
|
#define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3)
|
||||||
|
#define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12)
|
||||||
|
#define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4)
|
||||||
|
#define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5)
|
||||||
|
#define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12)
|
||||||
|
#define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13)
|
||||||
|
#define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9)
|
||||||
|
#define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15)
|
||||||
|
#define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11)
|
||||||
|
#define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
402
src/blake2b-load-sse41.h
Normal file
402
src/blake2b-load-sse41.h
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2B_LOAD_SSE41_H__
|
||||||
|
#define __BLAKE2B_LOAD_SSE41_H__
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m0, m1); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m2, m3); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m0, m1); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m2, m3); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m4, m5); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m4, m5); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m6, m7); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m7, m2); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m4, m6); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||||
|
b1 = _mm_alignr_epi8(m3, m7, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m5, m2); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m6, m1); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m3, m1); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_alignr_epi8(m6, m5, 8); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m2, m7); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m4, m0); \
|
||||||
|
b1 = _mm_blend_epi16(m1, m6, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m5, m1, 0xF0); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m3, m4); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m7, m3); \
|
||||||
|
b1 = _mm_alignr_epi8(m2, m0, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m3, m1); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m6, m5); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m4, m0); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m1, m2, 0xF0); \
|
||||||
|
b1 = _mm_blend_epi16(m2, m7, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m3, m5); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m0, m4); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m4, m2); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m1, m5); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m0, m3, 0xF0); \
|
||||||
|
b1 = _mm_blend_epi16(m2, m7, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m7, m5, 0xF0); \
|
||||||
|
b1 = _mm_blend_epi16(m3, m1, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_alignr_epi8(m6, m0, 8); \
|
||||||
|
b1 = _mm_blend_epi16(m4, m6, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m1, m3); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m0, m4); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m6, m5); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m5, m1); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m2, m3, 0xF0); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m7, m0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m6, m2); \
|
||||||
|
b1 = _mm_blend_epi16(m7, m4, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m6, m0, 0xF0); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m7, m2); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m2, m7); \
|
||||||
|
b1 = _mm_alignr_epi8(m5, m6, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m0, m3); \
|
||||||
|
b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m3, m1); \
|
||||||
|
b1 = _mm_blend_epi16(m1, m5, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m6, m3); \
|
||||||
|
b1 = _mm_blend_epi16(m6, m1, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_alignr_epi8(m7, m5, 8); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m0, m4); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m2, m7); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m4, m1); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m0, m2); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m3, m5); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m3, m7); \
|
||||||
|
b1 = _mm_alignr_epi8(m0, m5, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m7, m4); \
|
||||||
|
b1 = _mm_alignr_epi8(m4, m1, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = m6; \
|
||||||
|
b1 = _mm_alignr_epi8(m5, m0, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_blend_epi16(m1, m3, 0xF0); \
|
||||||
|
b1 = m2; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m3, m0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m1, m2); \
|
||||||
|
b1 = _mm_blend_epi16(m3, m2, 0xF0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m7, m4); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m1, m6); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_alignr_epi8(m7, m5, 8); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m6, m0); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_10_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m0, m1); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m2, m3); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_10_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m0, m1); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m2, m3); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_10_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m4, m5); \
|
||||||
|
b1 = _mm_unpacklo_epi64(m6, m7); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_10_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpackhi_epi64(m4, m5); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m6, m7); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_11_1(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m7, m2); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m4, m6); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_11_2(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m5, m4); \
|
||||||
|
b1 = _mm_alignr_epi8(m3, m7, 8); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_11_3(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m5, m2); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#define LOAD_MSG_11_4(b0, b1) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
b0 = _mm_unpacklo_epi64(m6, m1); \
|
||||||
|
b1 = _mm_unpackhi_epi64(m3, m1); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
381
src/blake2b-ref.c
Normal file
381
src/blake2b-ref.c
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
/*
|
||||||
|
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 "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
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( blake2b_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = ~0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_clear_lastnode( blake2b_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = 0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some helper functions, not necessarily useful */
|
||||||
|
static inline int blake2b_set_lastblock( blake2b_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2b_set_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = ~0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_clear_lastblock( blake2b_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2b_clear_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = 0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_increment_counter( 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( blake2b_param *P, const uint8_t digest_length )
|
||||||
|
{
|
||||||
|
P->digest_length = digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
|
||||||
|
{
|
||||||
|
P->fanout = fanout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
|
||||||
|
{
|
||||||
|
P->depth = depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
|
||||||
|
{
|
||||||
|
store32( &P->leaf_length, leaf_length );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
|
||||||
|
{
|
||||||
|
store64( &P->node_offset, node_offset );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
|
||||||
|
{
|
||||||
|
P->node_depth = node_depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
|
||||||
|
{
|
||||||
|
P->inner_length = inner_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_init0( blake2b_state *S )
|
||||||
|
{
|
||||||
|
memset( S, 0, sizeof( blake2b_state ) );
|
||||||
|
|
||||||
|
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init)
|
||||||
|
#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param)
|
||||||
|
#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key)
|
||||||
|
#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update)
|
||||||
|
#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final)
|
||||||
|
#define blake2b BLAKE2_IMPL_NAME(blake2b)
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int blake2b_init( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* init xors IV with input parameter block */
|
||||||
|
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||||
|
{
|
||||||
|
blake2b_init0( S );
|
||||||
|
uint8_t *p = ( uint8_t * )( P );
|
||||||
|
|
||||||
|
/* IV XOR ParamBlock */
|
||||||
|
for( size_t i = 0; i < 8; ++i )
|
||||||
|
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
|
||||||
|
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b_init( blake2b_state *S, size_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 blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_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( blake2b_state *S, const uint8_t block[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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b_update( blake2b_state *S, const uint8_t *in, size_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, inlen );
|
||||||
|
S->buflen += inlen; // Be lazy, do not compress
|
||||||
|
in += inlen;
|
||||||
|
inlen -= inlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
uint8_t buffer[BLAKE2B_OUTBYTES];
|
||||||
|
|
||||||
|
if(S->outlen != outlen) return -1;
|
||||||
|
|
||||||
|
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( int 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_state S[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if( NULL == key && keylen > 0 ) return -1;
|
||||||
|
|
||||||
|
if( keylen > 0 )
|
||||||
|
{
|
||||||
|
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0 ) return -1;
|
||||||
|
return blake2b_final( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
160
src/blake2b-round.h
Normal file
160
src/blake2b-round.h
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2B_ROUND_H__
|
||||||
|
#define __BLAKE2B_ROUND_H__
|
||||||
|
|
||||||
|
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
|
||||||
|
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||||
|
|
||||||
|
#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
|
||||||
|
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
|
||||||
|
|
||||||
|
#define TOF(reg) _mm_castsi128_ps((reg))
|
||||||
|
#define TOI(reg) _mm_castps_si128((reg))
|
||||||
|
|
||||||
|
#define LIKELY(x) __builtin_expect((x),1)
|
||||||
|
|
||||||
|
|
||||||
|
/* Microarchitecture-specific macros */
|
||||||
|
#ifndef HAVE_XOP
|
||||||
|
#ifdef HAVE_SSSE3
|
||||||
|
#define _mm_roti_epi64(x, c) \
|
||||||
|
(-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \
|
||||||
|
: (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \
|
||||||
|
: (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \
|
||||||
|
: (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \
|
||||||
|
: _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c))))
|
||||||
|
#else
|
||||||
|
#define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) ))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* ... */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||||
|
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||||
|
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||||
|
\
|
||||||
|
row4l = _mm_xor_si128(row4l, row1l); \
|
||||||
|
row4h = _mm_xor_si128(row4h, row1h); \
|
||||||
|
\
|
||||||
|
row4l = _mm_roti_epi64(row4l, -32); \
|
||||||
|
row4h = _mm_roti_epi64(row4h, -32); \
|
||||||
|
\
|
||||||
|
row3l = _mm_add_epi64(row3l, row4l); \
|
||||||
|
row3h = _mm_add_epi64(row3h, row4h); \
|
||||||
|
\
|
||||||
|
row2l = _mm_xor_si128(row2l, row3l); \
|
||||||
|
row2h = _mm_xor_si128(row2h, row3h); \
|
||||||
|
\
|
||||||
|
row2l = _mm_roti_epi64(row2l, -24); \
|
||||||
|
row2h = _mm_roti_epi64(row2h, -24); \
|
||||||
|
|
||||||
|
#define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \
|
||||||
|
row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \
|
||||||
|
row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \
|
||||||
|
\
|
||||||
|
row4l = _mm_xor_si128(row4l, row1l); \
|
||||||
|
row4h = _mm_xor_si128(row4h, row1h); \
|
||||||
|
\
|
||||||
|
row4l = _mm_roti_epi64(row4l, -16); \
|
||||||
|
row4h = _mm_roti_epi64(row4h, -16); \
|
||||||
|
\
|
||||||
|
row3l = _mm_add_epi64(row3l, row4l); \
|
||||||
|
row3h = _mm_add_epi64(row3h, row4h); \
|
||||||
|
\
|
||||||
|
row2l = _mm_xor_si128(row2l, row3l); \
|
||||||
|
row2h = _mm_xor_si128(row2h, row3h); \
|
||||||
|
\
|
||||||
|
row2l = _mm_roti_epi64(row2l, -63); \
|
||||||
|
row2h = _mm_roti_epi64(row2h, -63); \
|
||||||
|
|
||||||
|
#if defined(HAVE_SSSE3)
|
||||||
|
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||||
|
t0 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||||
|
t1 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||||
|
row2l = t0; \
|
||||||
|
row2h = t1; \
|
||||||
|
\
|
||||||
|
t0 = row3l; \
|
||||||
|
row3l = row3h; \
|
||||||
|
row3h = t0; \
|
||||||
|
\
|
||||||
|
t0 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||||
|
t1 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||||
|
row4l = t1; \
|
||||||
|
row4h = t0;
|
||||||
|
|
||||||
|
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||||
|
t0 = _mm_alignr_epi8(row2l, row2h, 8); \
|
||||||
|
t1 = _mm_alignr_epi8(row2h, row2l, 8); \
|
||||||
|
row2l = t0; \
|
||||||
|
row2h = t1; \
|
||||||
|
\
|
||||||
|
t0 = row3l; \
|
||||||
|
row3l = row3h; \
|
||||||
|
row3h = t0; \
|
||||||
|
\
|
||||||
|
t0 = _mm_alignr_epi8(row4l, row4h, 8); \
|
||||||
|
t1 = _mm_alignr_epi8(row4h, row4l, 8); \
|
||||||
|
row4l = t1; \
|
||||||
|
row4h = t0;
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||||
|
t0 = row4l;\
|
||||||
|
t1 = row2l;\
|
||||||
|
row4l = row3l;\
|
||||||
|
row3l = row3h;\
|
||||||
|
row3h = row4l;\
|
||||||
|
row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \
|
||||||
|
row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||||
|
row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||||
|
row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1))
|
||||||
|
|
||||||
|
#define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \
|
||||||
|
t0 = row3l;\
|
||||||
|
row3l = row3h;\
|
||||||
|
row3h = t0;\
|
||||||
|
t0 = row2l;\
|
||||||
|
t1 = row4l;\
|
||||||
|
row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \
|
||||||
|
row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \
|
||||||
|
row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \
|
||||||
|
row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SSE4_1)
|
||||||
|
#include "blake2b-load-sse41.h"
|
||||||
|
#else
|
||||||
|
#include "blake2b-load-sse2.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ROUND(r) \
|
||||||
|
LOAD_MSG_ ##r ##_1(b0, b1); \
|
||||||
|
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||||
|
LOAD_MSG_ ##r ##_2(b0, b1); \
|
||||||
|
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||||
|
DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \
|
||||||
|
LOAD_MSG_ ##r ##_3(b0, b1); \
|
||||||
|
G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||||
|
LOAD_MSG_ ##r ##_4(b0, b1); \
|
||||||
|
G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \
|
||||||
|
UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
43
src/blake2b-test.c
Normal file
43
src/blake2b-test.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "blake2.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];
|
||||||
|
|
||||||
|
if( blake2b( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 ||
|
||||||
|
0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||||
|
{
|
||||||
|
puts( "error" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts( "ok" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
439
src/blake2b.c
Normal file
439
src/blake2b.c
Normal file
@ -0,0 +1,439 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
#include "blake2-config.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SSE2)
|
||||||
|
#include <emmintrin.h>
|
||||||
|
// MSVC only defines _mm_set_epi64x for x86_64...
|
||||||
|
#if defined(_MSC_VER) && !defined(_M_X64)
|
||||||
|
static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
|
||||||
|
{
|
||||||
|
return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SSSE3)
|
||||||
|
#include <tmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_SSE4_1)
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_AVX)
|
||||||
|
#include <immintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_XOP) && !defined(_MSC_VER)
|
||||||
|
#include <x86intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "blake2b-round.h"
|
||||||
|
|
||||||
|
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 }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Some helper functions, not necessarily useful */
|
||||||
|
static inline int blake2b_set_lastnode( blake2b_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = ~0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_clear_lastnode( blake2b_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = 0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_set_lastblock( blake2b_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2b_set_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = ~0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_clear_lastblock( blake2b_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2b_clear_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = 0ULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
|
||||||
|
{
|
||||||
|
#if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__))
|
||||||
|
// ADD/ADC chain
|
||||||
|
__uint128_t t = ( ( __uint128_t )S->t[1] << 64 ) | S->t[0];
|
||||||
|
t += inc;
|
||||||
|
S->t[0] = ( uint64_t )( t >> 0 );
|
||||||
|
S->t[1] = ( uint64_t )( t >> 64 );
|
||||||
|
#else
|
||||||
|
S->t[0] += inc;
|
||||||
|
S->t[1] += ( S->t[0] < inc );
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parameter-related functions
|
||||||
|
static inline int blake2b_param_set_digest_length( blake2b_param *P, const uint8_t digest_length )
|
||||||
|
{
|
||||||
|
P->digest_length = digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_fanout( blake2b_param *P, const uint8_t fanout )
|
||||||
|
{
|
||||||
|
P->fanout = fanout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_max_depth( blake2b_param *P, const uint8_t depth )
|
||||||
|
{
|
||||||
|
P->depth = depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_leaf_length( blake2b_param *P, const uint32_t leaf_length )
|
||||||
|
{
|
||||||
|
P->leaf_length = leaf_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_node_offset( blake2b_param *P, const uint64_t node_offset )
|
||||||
|
{
|
||||||
|
P->node_offset = node_offset;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_node_depth( blake2b_param *P, const uint8_t node_depth )
|
||||||
|
{
|
||||||
|
P->node_depth = node_depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_inner_length( blake2b_param *P, const uint8_t inner_length )
|
||||||
|
{
|
||||||
|
P->inner_length = inner_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_salt( blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->salt, salt, BLAKE2B_SALTBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_param_set_personal( blake2b_param *P, const uint8_t personal[BLAKE2B_PERSONALBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->personal, personal, BLAKE2B_PERSONALBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2b_init0( blake2b_state *S )
|
||||||
|
{
|
||||||
|
memset( S, 0, sizeof( blake2b_state ) );
|
||||||
|
|
||||||
|
for( int i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define blake2b_init BLAKE2_IMPL_NAME(blake2b_init)
|
||||||
|
#define blake2b_init_param BLAKE2_IMPL_NAME(blake2b_init_param)
|
||||||
|
#define blake2b_init_key BLAKE2_IMPL_NAME(blake2b_init_key)
|
||||||
|
#define blake2b_update BLAKE2_IMPL_NAME(blake2b_update)
|
||||||
|
#define blake2b_final BLAKE2_IMPL_NAME(blake2b_final)
|
||||||
|
#define blake2b BLAKE2_IMPL_NAME(blake2b)
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int blake2b_init( blake2b_state *S, size_t outlen );
|
||||||
|
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
|
||||||
|
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2b_update( blake2b_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* init xors IV with input parameter block */
|
||||||
|
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
|
||||||
|
{
|
||||||
|
uint8_t *p, *h, *v;
|
||||||
|
//blake2b_init0( S );
|
||||||
|
v = ( uint8_t * )( blake2b_IV );
|
||||||
|
h = ( uint8_t * )( S->h );
|
||||||
|
p = ( uint8_t * )( P );
|
||||||
|
/* IV XOR ParamBlock */
|
||||||
|
memset( S, 0, sizeof( blake2b_state ) );
|
||||||
|
|
||||||
|
for( int i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
|
||||||
|
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Some sort of default parameter block initialization, for sequential blake2b */
|
||||||
|
|
||||||
|
int blake2b_init( blake2b_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
const blake2b_param P =
|
||||||
|
{
|
||||||
|
outlen,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{0},
|
||||||
|
{0},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
return blake2b_init_param( S, &P );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
const blake2b_param P =
|
||||||
|
{
|
||||||
|
outlen,
|
||||||
|
keylen,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{0},
|
||||||
|
{0},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
if( blake2b_init_param( S, &P ) < 0 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
{
|
||||||
|
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 inline int blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
|
||||||
|
{
|
||||||
|
__m128i row1l, row1h;
|
||||||
|
__m128i row2l, row2h;
|
||||||
|
__m128i row3l, row3h;
|
||||||
|
__m128i row4l, row4h;
|
||||||
|
__m128i b0, b1;
|
||||||
|
__m128i t0, t1;
|
||||||
|
#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
|
||||||
|
const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 );
|
||||||
|
const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 );
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_SSE4_1)
|
||||||
|
const __m128i m0 = LOADU( block + 00 );
|
||||||
|
const __m128i m1 = LOADU( block + 16 );
|
||||||
|
const __m128i m2 = LOADU( block + 32 );
|
||||||
|
const __m128i m3 = LOADU( block + 48 );
|
||||||
|
const __m128i m4 = LOADU( block + 64 );
|
||||||
|
const __m128i m5 = LOADU( block + 80 );
|
||||||
|
const __m128i m6 = LOADU( block + 96 );
|
||||||
|
const __m128i m7 = LOADU( block + 112 );
|
||||||
|
#else
|
||||||
|
const uint64_t m0 = ( ( uint64_t * )block )[ 0];
|
||||||
|
const uint64_t m1 = ( ( uint64_t * )block )[ 1];
|
||||||
|
const uint64_t m2 = ( ( uint64_t * )block )[ 2];
|
||||||
|
const uint64_t m3 = ( ( uint64_t * )block )[ 3];
|
||||||
|
const uint64_t m4 = ( ( uint64_t * )block )[ 4];
|
||||||
|
const uint64_t m5 = ( ( uint64_t * )block )[ 5];
|
||||||
|
const uint64_t m6 = ( ( uint64_t * )block )[ 6];
|
||||||
|
const uint64_t m7 = ( ( uint64_t * )block )[ 7];
|
||||||
|
const uint64_t m8 = ( ( uint64_t * )block )[ 8];
|
||||||
|
const uint64_t m9 = ( ( uint64_t * )block )[ 9];
|
||||||
|
const uint64_t m10 = ( ( uint64_t * )block )[10];
|
||||||
|
const uint64_t m11 = ( ( uint64_t * )block )[11];
|
||||||
|
const uint64_t m12 = ( ( uint64_t * )block )[12];
|
||||||
|
const uint64_t m13 = ( ( uint64_t * )block )[13];
|
||||||
|
const uint64_t m14 = ( ( uint64_t * )block )[14];
|
||||||
|
const uint64_t m15 = ( ( uint64_t * )block )[15];
|
||||||
|
#endif
|
||||||
|
row1l = LOADU( &S->h[0] );
|
||||||
|
row1h = LOADU( &S->h[2] );
|
||||||
|
row2l = LOADU( &S->h[4] );
|
||||||
|
row2h = LOADU( &S->h[6] );
|
||||||
|
row3l = LOADU( &blake2b_IV[0] );
|
||||||
|
row3h = LOADU( &blake2b_IV[2] );
|
||||||
|
row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) );
|
||||||
|
row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[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 );
|
||||||
|
row1l = _mm_xor_si128( row3l, row1l );
|
||||||
|
row1h = _mm_xor_si128( row3h, row1h );
|
||||||
|
STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) );
|
||||||
|
STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) );
|
||||||
|
row2l = _mm_xor_si128( row4l, row2l );
|
||||||
|
row2h = _mm_xor_si128( row4h, row2h );
|
||||||
|
STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) );
|
||||||
|
STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b_update( blake2b_state *S, const uint8_t *in, size_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, inlen );
|
||||||
|
S->buflen += inlen; // Be lazy, do not compress
|
||||||
|
in += inlen;
|
||||||
|
inlen -= inlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b_final( blake2b_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
if(S->outlen != outlen) return -1;
|
||||||
|
|
||||||
|
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 );
|
||||||
|
memcpy( out, &S->h[0], outlen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2b( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_state S[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if( NULL == key && keylen > 0 ) return -1;
|
||||||
|
|
||||||
|
if( keylen )
|
||||||
|
{
|
||||||
|
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( blake2b_init( S, outlen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blake2b_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
|
||||||
|
return blake2b_final( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SUPERCOP)
|
||||||
|
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||||
|
{
|
||||||
|
return blake2b( out, in, NULL, BLAKE2B_OUTBYTES, inlen, 0 );
|
||||||
|
}
|
||||||
|
#endif
|
44
src/blake2bp-test.c
Normal file
44
src/blake2bp-test.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "blake2.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];
|
||||||
|
|
||||||
|
if( blake2bp( hash, buf, key, BLAKE2B_OUTBYTES, i, BLAKE2B_KEYBYTES ) < 0 ||
|
||||||
|
0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) )
|
||||||
|
{
|
||||||
|
puts( "error" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts( "ok" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
272
src/blake2bp.c
Normal file
272
src/blake2bp.c
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
#include <omp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
#define PARALLELISM_DEGREE 4
|
||||||
|
|
||||||
|
static int blake2bp_init_leaf( blake2b_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
|
||||||
|
{
|
||||||
|
blake2b_param P[1];
|
||||||
|
P->digest_length = outlen;
|
||||||
|
P->key_length = keylen;
|
||||||
|
P->fanout = PARALLELISM_DEGREE;
|
||||||
|
P->depth = 2;
|
||||||
|
P->leaf_length = 0;
|
||||||
|
P->node_offset = offset;
|
||||||
|
P->node_depth = 0;
|
||||||
|
P->inner_length = BLAKE2B_OUTBYTES;
|
||||||
|
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||||
|
memset( P->salt, 0, sizeof( P->salt ) );
|
||||||
|
memset( P->personal, 0, sizeof( P->personal ) );
|
||||||
|
blake2b_init_param( S, P );
|
||||||
|
S->outlen = P->inner_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int blake2bp_init_root( blake2b_state *S, uint8_t outlen, uint8_t keylen )
|
||||||
|
{
|
||||||
|
blake2b_param P[1];
|
||||||
|
P->digest_length = outlen;
|
||||||
|
P->key_length = keylen;
|
||||||
|
P->fanout = PARALLELISM_DEGREE;
|
||||||
|
P->depth = 2;
|
||||||
|
P->leaf_length = 0;
|
||||||
|
P->node_offset = 0;
|
||||||
|
P->node_depth = 1;
|
||||||
|
P->inner_length = BLAKE2B_OUTBYTES;
|
||||||
|
memset( P->reserved, 0, sizeof( P->reserved ) );
|
||||||
|
memset( P->salt, 0, sizeof( P->salt ) );
|
||||||
|
memset( P->personal, 0, sizeof( P->personal ) );
|
||||||
|
blake2b_init_param( S, P );
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2bp_init( blake2bp_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
memset( S->buf, 0, sizeof( S->buf ) );
|
||||||
|
S->buflen = 0;
|
||||||
|
|
||||||
|
if( blake2bp_init_root( S->R, outlen, 0 ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
|
||||||
|
|
||||||
|
S->R->last_node = 1;
|
||||||
|
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||||
|
S->outlen = outlen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
memset( S->buf, 0, sizeof( S->buf ) );
|
||||||
|
S->buflen = 0;
|
||||||
|
|
||||||
|
if( blake2bp_init_root( S->R, outlen, keylen ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||||
|
|
||||||
|
S->R->last_node = 1;
|
||||||
|
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||||
|
S->outlen = outlen;
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES );
|
||||||
|
|
||||||
|
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2bp_update( blake2bp_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen;
|
||||||
|
size_t fill = sizeof( S->buf ) - left;
|
||||||
|
|
||||||
|
if( left && inlen >= fill )
|
||||||
|
{
|
||||||
|
memcpy( S->buf + left, in, fill );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES );
|
||||||
|
|
||||||
|
in += fill;
|
||||||
|
inlen -= fill;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
omp_set_num_threads(PARALLELISM_DEGREE);
|
||||||
|
#pragma omp parallel shared(S)
|
||||||
|
#else
|
||||||
|
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
size_t id__ = omp_get_thread_num();
|
||||||
|
#endif
|
||||||
|
size_t inlen__ = inlen;
|
||||||
|
const uint8_t *in__ = ( const uint8_t * )in;
|
||||||
|
in__ += id__ * BLAKE2B_BLOCKBYTES;
|
||||||
|
|
||||||
|
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
blake2b_update( S->S[id__], in__, BLAKE2B_BLOCKBYTES );
|
||||||
|
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||||
|
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES );
|
||||||
|
inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||||
|
|
||||||
|
if( inlen > 0 )
|
||||||
|
memcpy( S->buf + left, in, inlen );
|
||||||
|
|
||||||
|
S->buflen = left + inlen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int blake2bp_final( blake2bp_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
|
||||||
|
|
||||||
|
if(S->outlen != outlen) return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
{
|
||||||
|
if( S->buflen > i * BLAKE2B_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES;
|
||||||
|
|
||||||
|
if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES;
|
||||||
|
|
||||||
|
blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left );
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES );
|
||||||
|
|
||||||
|
return blake2b_final( S->R, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2bp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES];
|
||||||
|
blake2b_state S[PARALLELISM_DEGREE][1];
|
||||||
|
blake2b_state FS[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == key && keylen > 0) return -1;
|
||||||
|
|
||||||
|
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
if( keylen > BLAKE2B_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||||
|
|
||||||
|
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
|
||||||
|
|
||||||
|
if( keylen > 0 )
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2B_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2B_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES );
|
||||||
|
|
||||||
|
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
omp_set_num_threads(PARALLELISM_DEGREE);
|
||||||
|
#pragma omp parallel shared(S,hash)
|
||||||
|
#else
|
||||||
|
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
size_t id__ = omp_get_thread_num();
|
||||||
|
#endif
|
||||||
|
size_t inlen__ = inlen;
|
||||||
|
const uint8_t *in__ = ( const uint8_t * )in;
|
||||||
|
in__ += id__ * BLAKE2B_BLOCKBYTES;
|
||||||
|
|
||||||
|
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES );
|
||||||
|
in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||||
|
inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inlen__ > id__ * BLAKE2B_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES;
|
||||||
|
const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES;
|
||||||
|
blake2b_update( S[id__], in__, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blake2bp_init_root( FS, outlen, keylen ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FS->last_node = 1; // Mark as last node
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES );
|
||||||
|
|
||||||
|
return blake2b_final( FS, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
59
src/blake2s-load-sse2.h
Normal file
59
src/blake2s-load-sse2.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2S_LOAD_SSE2_H__
|
||||||
|
#define __BLAKE2S_LOAD_SSE2_H__
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0)
|
||||||
|
#define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1)
|
||||||
|
#define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8)
|
||||||
|
#define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9)
|
||||||
|
#define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14)
|
||||||
|
#define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10)
|
||||||
|
#define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1)
|
||||||
|
#define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12)
|
||||||
|
#define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11)
|
||||||
|
#define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8)
|
||||||
|
#define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10)
|
||||||
|
#define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14)
|
||||||
|
#define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7)
|
||||||
|
#define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9)
|
||||||
|
#define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2)
|
||||||
|
#define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6)
|
||||||
|
#define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9)
|
||||||
|
#define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0)
|
||||||
|
#define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14)
|
||||||
|
#define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1)
|
||||||
|
#define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2)
|
||||||
|
#define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12)
|
||||||
|
#define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4)
|
||||||
|
#define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13)
|
||||||
|
#define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12)
|
||||||
|
#define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5)
|
||||||
|
#define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0)
|
||||||
|
#define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7)
|
||||||
|
#define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13)
|
||||||
|
#define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11)
|
||||||
|
#define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5)
|
||||||
|
#define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0)
|
||||||
|
#define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6)
|
||||||
|
#define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15)
|
||||||
|
#define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12)
|
||||||
|
#define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2)
|
||||||
|
#define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10)
|
||||||
|
#define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2)
|
||||||
|
#define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15)
|
||||||
|
#define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
229
src/blake2s-load-sse41.h
Normal file
229
src/blake2s-load-sse41.h
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2S_LOAD_SSE41_H__
|
||||||
|
#define __BLAKE2S_LOAD_SSE41_H__
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_1(buf) \
|
||||||
|
buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0)));
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_2(buf) \
|
||||||
|
buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1)));
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_3(buf) \
|
||||||
|
buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0)));
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_4(buf) \
|
||||||
|
buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1)));
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_1(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m1, m2, 0x0C); \
|
||||||
|
t1 = _mm_slli_si128(m3, 4); \
|
||||||
|
t2 = _mm_blend_epi16(t0, t1, 0xF0); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_2(buf) \
|
||||||
|
t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \
|
||||||
|
t1 = _mm_blend_epi16(m1,m3,0xC0); \
|
||||||
|
t2 = _mm_blend_epi16(t0, t1, 0xF0); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_3(buf) \
|
||||||
|
t0 = _mm_slli_si128(m1, 4); \
|
||||||
|
t1 = _mm_blend_epi16(m2, t0, 0x30); \
|
||||||
|
t2 = _mm_blend_epi16(m0, t1, 0xF0); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_4(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||||
|
t1 = _mm_slli_si128(m3, 4); \
|
||||||
|
t2 = _mm_blend_epi16(t0, t1, 0x0C); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1));
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_1(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m2,m3); \
|
||||||
|
t1 = _mm_blend_epi16(m3,m1,0x0C); \
|
||||||
|
t2 = _mm_blend_epi16(t0, t1, 0x0F); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_2(buf) \
|
||||||
|
t0 = _mm_unpacklo_epi32(m2,m0); \
|
||||||
|
t1 = _mm_blend_epi16(t0, m0, 0xF0); \
|
||||||
|
t2 = _mm_slli_si128(m3, 8); \
|
||||||
|
buf = _mm_blend_epi16(t1, t2, 0xC0);
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_3(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m0, m2, 0x3C); \
|
||||||
|
t1 = _mm_srli_si128(m1, 12); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x03); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_4(buf) \
|
||||||
|
t0 = _mm_slli_si128(m3, 4); \
|
||||||
|
t1 = _mm_blend_epi16(m0, m1, 0x33); \
|
||||||
|
t2 = _mm_blend_epi16(t1, t0, 0xC0); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_1(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||||
|
t1 = _mm_unpackhi_epi32(t0, m2); \
|
||||||
|
t2 = _mm_blend_epi16(t1, m3, 0x0C); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_2(buf) \
|
||||||
|
t0 = _mm_slli_si128(m2, 8); \
|
||||||
|
t1 = _mm_blend_epi16(m3,m0,0x0C); \
|
||||||
|
t2 = _mm_blend_epi16(t1, t0, 0xC0); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_3(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m0,m1,0x0F); \
|
||||||
|
t1 = _mm_blend_epi16(t0, m3, 0xC0); \
|
||||||
|
buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_4(buf) \
|
||||||
|
t0 = _mm_unpacklo_epi32(m0,m2); \
|
||||||
|
t1 = _mm_unpackhi_epi32(m1,m2); \
|
||||||
|
buf = _mm_unpacklo_epi64(t1,t0);
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_1(buf) \
|
||||||
|
t0 = _mm_unpacklo_epi64(m1,m2); \
|
||||||
|
t1 = _mm_unpackhi_epi64(m0,m2); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x33); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_2(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi64(m1,m3); \
|
||||||
|
t1 = _mm_unpacklo_epi64(m0,m1); \
|
||||||
|
buf = _mm_blend_epi16(t0,t1,0x33);
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_3(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi64(m3,m1); \
|
||||||
|
t1 = _mm_unpackhi_epi64(m2,m0); \
|
||||||
|
buf = _mm_blend_epi16(t1,t0,0x33);
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_4(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m0,m2,0x03); \
|
||||||
|
t1 = _mm_slli_si128(t0, 8); \
|
||||||
|
t2 = _mm_blend_epi16(t1,m3,0x0F); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_1(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||||
|
t1 = _mm_unpacklo_epi32(m0,m2); \
|
||||||
|
buf = _mm_unpacklo_epi64(t0,t1);
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_2(buf) \
|
||||||
|
t0 = _mm_srli_si128(m2, 4); \
|
||||||
|
t1 = _mm_blend_epi16(m0,m3,0x03); \
|
||||||
|
buf = _mm_blend_epi16(t1,t0,0x3C);
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_3(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m1,m0,0x0C); \
|
||||||
|
t1 = _mm_srli_si128(m3, 4); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x30); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0));
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_4(buf) \
|
||||||
|
t0 = _mm_unpacklo_epi64(m1,m2); \
|
||||||
|
t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \
|
||||||
|
buf = _mm_blend_epi16(t0,t1,0x33);
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_1(buf) \
|
||||||
|
t0 = _mm_slli_si128(m1, 12); \
|
||||||
|
t1 = _mm_blend_epi16(m0,m3,0x33); \
|
||||||
|
buf = _mm_blend_epi16(t1,t0,0xC0);
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_2(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m3,m2,0x30); \
|
||||||
|
t1 = _mm_srli_si128(m1, 4); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x03); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0));
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_3(buf) \
|
||||||
|
t0 = _mm_unpacklo_epi64(m0,m2); \
|
||||||
|
t1 = _mm_srli_si128(m1, 4); \
|
||||||
|
buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0));
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_4(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m1,m2); \
|
||||||
|
t1 = _mm_unpackhi_epi64(m0,t0); \
|
||||||
|
buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_1(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m0,m1); \
|
||||||
|
t1 = _mm_blend_epi16(t0,m3,0x0F); \
|
||||||
|
buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1));
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_2(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m2,m3,0x30); \
|
||||||
|
t1 = _mm_srli_si128(m0,4); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x03); \
|
||||||
|
buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_3(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi64(m0,m3); \
|
||||||
|
t1 = _mm_unpacklo_epi64(m1,m2); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x3C); \
|
||||||
|
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1));
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_4(buf) \
|
||||||
|
t0 = _mm_unpacklo_epi32(m0,m1); \
|
||||||
|
t1 = _mm_unpackhi_epi32(m1,m2); \
|
||||||
|
buf = _mm_unpacklo_epi64(t0,t1);
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_1(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m1,m3); \
|
||||||
|
t1 = _mm_unpacklo_epi64(t0,m0); \
|
||||||
|
t2 = _mm_blend_epi16(t1,m2,0xC0); \
|
||||||
|
buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_2(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m0,m3); \
|
||||||
|
t1 = _mm_blend_epi16(m2,t0,0xF0); \
|
||||||
|
buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_3(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m2,m0,0x0C); \
|
||||||
|
t1 = _mm_slli_si128(t0,4); \
|
||||||
|
buf = _mm_blend_epi16(t1,m3,0x0F);
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_4(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m1,m0,0x30); \
|
||||||
|
buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_1(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m0,m2,0x03); \
|
||||||
|
t1 = _mm_blend_epi16(m1,m2,0x30); \
|
||||||
|
t2 = _mm_blend_epi16(t1,t0,0x0F); \
|
||||||
|
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2));
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_2(buf) \
|
||||||
|
t0 = _mm_slli_si128(m0,4); \
|
||||||
|
t1 = _mm_blend_epi16(m1,t0,0xC0); \
|
||||||
|
buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3));
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_3(buf) \
|
||||||
|
t0 = _mm_unpackhi_epi32(m0,m3); \
|
||||||
|
t1 = _mm_unpacklo_epi32(m2,m3); \
|
||||||
|
t2 = _mm_unpackhi_epi64(t0,t1); \
|
||||||
|
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1));
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_4(buf) \
|
||||||
|
t0 = _mm_blend_epi16(m3,m2,0xC0); \
|
||||||
|
t1 = _mm_unpacklo_epi32(m0,m3); \
|
||||||
|
t2 = _mm_blend_epi16(t0,t1,0x0F); \
|
||||||
|
buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3));
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
189
src/blake2s-load-xop.h
Normal file
189
src/blake2s-load-xop.h
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2S_LOAD_XOP_H__
|
||||||
|
#define __BLAKE2S_LOAD_XOP_H__
|
||||||
|
|
||||||
|
#define TOB(x) ((x)*4*0x01010101 + 0x03020100) // ..or not TOB
|
||||||
|
|
||||||
|
/* Basic VPPERM emulation, for testing purposes */
|
||||||
|
/*static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel)
|
||||||
|
{
|
||||||
|
const __m128i sixteen = _mm_set1_epi8(16);
|
||||||
|
const __m128i t0 = _mm_shuffle_epi8(src1, sel);
|
||||||
|
const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen));
|
||||||
|
const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen),
|
||||||
|
_mm_cmpgt_epi8(sel, sixteen)); // (>=16) = 0xff : 00
|
||||||
|
return _mm_blendv_epi8(t0, s1, mask);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_1(buf) \
|
||||||
|
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_2(buf) \
|
||||||
|
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_3(buf) \
|
||||||
|
buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_0_4(buf) \
|
||||||
|
buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_1_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_2_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \
|
||||||
|
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_3_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \
|
||||||
|
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_4_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_5_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_6_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \
|
||||||
|
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_7_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \
|
||||||
|
t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_2(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \
|
||||||
|
|
||||||
|
#define LOAD_MSG_8_4(buf) \
|
||||||
|
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_1(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_2(buf) \
|
||||||
|
buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_3(buf) \
|
||||||
|
t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \
|
||||||
|
buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) );
|
||||||
|
|
||||||
|
#define LOAD_MSG_9_4(buf) \
|
||||||
|
t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \
|
||||||
|
buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) );
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
370
src/blake2s-ref.c
Normal file
370
src/blake2s-ref.c
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
/*
|
||||||
|
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 "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
static const uint32_t blake2s_IV[8] =
|
||||||
|
{
|
||||||
|
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||||
|
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t blake2s_sigma[10][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 } ,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline int blake2s_set_lastnode( blake2s_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = ~0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_clear_lastnode( blake2s_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = 0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some helper functions, not necessarily useful */
|
||||||
|
static inline int blake2s_set_lastblock( blake2s_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2s_set_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = ~0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_clear_lastblock( blake2s_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2s_clear_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = 0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
||||||
|
{
|
||||||
|
S->t[0] += inc;
|
||||||
|
S->t[1] += ( S->t[0] < inc );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter-related functions
|
||||||
|
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
|
||||||
|
{
|
||||||
|
P->digest_length = digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
|
||||||
|
{
|
||||||
|
P->fanout = fanout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
|
||||||
|
{
|
||||||
|
P->depth = depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
|
||||||
|
{
|
||||||
|
store32( &P->leaf_length, leaf_length );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
|
||||||
|
{
|
||||||
|
store48( P->node_offset, node_offset );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
|
||||||
|
{
|
||||||
|
P->node_depth = node_depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
|
||||||
|
{
|
||||||
|
P->inner_length = inner_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_init0( blake2s_state *S )
|
||||||
|
{
|
||||||
|
memset( S, 0, sizeof( blake2s_state ) );
|
||||||
|
|
||||||
|
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init)
|
||||||
|
#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param)
|
||||||
|
#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key)
|
||||||
|
#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update)
|
||||||
|
#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final)
|
||||||
|
#define blake2s BLAKE2_IMPL_NAME(blake2s)
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int blake2s_init( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* init2 xors IV with input parameter block */
|
||||||
|
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||||
|
{
|
||||||
|
blake2s_init0( S );
|
||||||
|
uint32_t *p = ( uint32_t * )( P );
|
||||||
|
|
||||||
|
/* IV XOR ParamBlock */
|
||||||
|
for( size_t i = 0; i < 8; ++i )
|
||||||
|
S->h[i] ^= load32( &p[i] );
|
||||||
|
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sequential blake2s initialization
|
||||||
|
int blake2s_init( blake2s_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
blake2s_param P[1];
|
||||||
|
|
||||||
|
/* Move interval verification here? */
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
P->digest_length = outlen;
|
||||||
|
P->key_length = 0;
|
||||||
|
P->fanout = 1;
|
||||||
|
P->depth = 1;
|
||||||
|
store32( &P->leaf_length, 0 );
|
||||||
|
store48( &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 blake2s_init_param( S, P );
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2s_param P[1];
|
||||||
|
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
P->digest_length = outlen;
|
||||||
|
P->key_length = keylen;
|
||||||
|
P->fanout = 1;
|
||||||
|
P->depth = 1;
|
||||||
|
store32( &P->leaf_length, 0 );
|
||||||
|
store48( &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( blake2s_init_param( S, P ) < 0 ) return -1;
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
||||||
|
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
|
||||||
|
{
|
||||||
|
uint32_t m[16];
|
||||||
|
uint32_t v[16];
|
||||||
|
|
||||||
|
for( size_t i = 0; i < 16; ++i )
|
||||||
|
m[i] = load32( block + i * sizeof( m[i] ) );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < 8; ++i )
|
||||||
|
v[i] = S->h[i];
|
||||||
|
|
||||||
|
v[ 8] = blake2s_IV[0];
|
||||||
|
v[ 9] = blake2s_IV[1];
|
||||||
|
v[10] = blake2s_IV[2];
|
||||||
|
v[11] = blake2s_IV[3];
|
||||||
|
v[12] = S->t[0] ^ blake2s_IV[4];
|
||||||
|
v[13] = S->t[1] ^ blake2s_IV[5];
|
||||||
|
v[14] = S->f[0] ^ blake2s_IV[6];
|
||||||
|
v[15] = S->f[1] ^ blake2s_IV[7];
|
||||||
|
#define G(r,i,a,b,c,d) \
|
||||||
|
do { \
|
||||||
|
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
|
||||||
|
d = rotr32(d ^ a, 16); \
|
||||||
|
c = c + d; \
|
||||||
|
b = rotr32(b ^ c, 12); \
|
||||||
|
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
|
||||||
|
d = rotr32(d ^ a, 8); \
|
||||||
|
c = c + d; \
|
||||||
|
b = rotr32(b ^ c, 7); \
|
||||||
|
} 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 );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < 8; ++i )
|
||||||
|
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
|
||||||
|
|
||||||
|
#undef G
|
||||||
|
#undef ROUND
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
while( inlen > 0 )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen;
|
||||||
|
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
||||||
|
|
||||||
|
if( inlen > fill )
|
||||||
|
{
|
||||||
|
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||||
|
S->buflen += fill;
|
||||||
|
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||||
|
blake2s_compress( S, S->buf ); // Compress
|
||||||
|
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
|
||||||
|
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||||
|
in += fill;
|
||||||
|
inlen -= fill;
|
||||||
|
}
|
||||||
|
else // inlen <= fill
|
||||||
|
{
|
||||||
|
memcpy( S->buf + left, in, inlen );
|
||||||
|
S->buflen += inlen; // Be lazy, do not compress
|
||||||
|
in += inlen;
|
||||||
|
inlen -= inlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
uint8_t buffer[BLAKE2S_OUTBYTES];
|
||||||
|
|
||||||
|
if(S->outlen != outlen) return -1;
|
||||||
|
|
||||||
|
if( S->buflen > BLAKE2S_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||||
|
blake2s_compress( S, S->buf );
|
||||||
|
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||||
|
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
||||||
|
blake2s_set_lastblock( S );
|
||||||
|
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||||
|
blake2s_compress( S, S->buf );
|
||||||
|
|
||||||
|
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||||
|
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||||
|
|
||||||
|
memcpy( out, buffer, outlen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2s_state S[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == key && keylen > 0 ) return -1;
|
||||||
|
|
||||||
|
if( keylen > 0 )
|
||||||
|
{
|
||||||
|
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
|
||||||
|
return blake2s_final( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
91
src/blake2s-round.h
Normal file
91
src/blake2s-round.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 __BLAKE2S_ROUND_H__
|
||||||
|
#define __BLAKE2S_ROUND_H__
|
||||||
|
|
||||||
|
#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
|
||||||
|
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)
|
||||||
|
|
||||||
|
#define LOADU(p) _mm_loadu_si128( (__m128i *)(p) )
|
||||||
|
#define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r)
|
||||||
|
|
||||||
|
#define TOF(reg) _mm_castsi128_ps((reg))
|
||||||
|
#define TOI(reg) _mm_castps_si128((reg))
|
||||||
|
|
||||||
|
#define LIKELY(x) __builtin_expect((x),1)
|
||||||
|
|
||||||
|
|
||||||
|
/* Microarchitecture-specific macros */
|
||||||
|
#ifndef HAVE_XOP
|
||||||
|
#ifdef HAVE_SSSE3
|
||||||
|
#define _mm_roti_epi32(r, c) ( \
|
||||||
|
(8==-(c)) ? _mm_shuffle_epi8(r,r8) \
|
||||||
|
: (16==-(c)) ? _mm_shuffle_epi8(r,r16) \
|
||||||
|
: _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) )
|
||||||
|
#else
|
||||||
|
#define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) ))
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* ... */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define G1(row1,row2,row3,row4,buf) \
|
||||||
|
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||||
|
row4 = _mm_xor_si128( row4, row1 ); \
|
||||||
|
row4 = _mm_roti_epi32(row4, -16); \
|
||||||
|
row3 = _mm_add_epi32( row3, row4 ); \
|
||||||
|
row2 = _mm_xor_si128( row2, row3 ); \
|
||||||
|
row2 = _mm_roti_epi32(row2, -12);
|
||||||
|
|
||||||
|
#define G2(row1,row2,row3,row4,buf) \
|
||||||
|
row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \
|
||||||
|
row4 = _mm_xor_si128( row4, row1 ); \
|
||||||
|
row4 = _mm_roti_epi32(row4, -8); \
|
||||||
|
row3 = _mm_add_epi32( row3, row4 ); \
|
||||||
|
row2 = _mm_xor_si128( row2, row3 ); \
|
||||||
|
row2 = _mm_roti_epi32(row2, -7);
|
||||||
|
|
||||||
|
#define DIAGONALIZE(row1,row2,row3,row4) \
|
||||||
|
row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \
|
||||||
|
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||||
|
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) );
|
||||||
|
|
||||||
|
#define UNDIAGONALIZE(row1,row2,row3,row4) \
|
||||||
|
row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \
|
||||||
|
row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \
|
||||||
|
row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) );
|
||||||
|
|
||||||
|
#if defined(HAVE_XOP)
|
||||||
|
#include "blake2s-load-xop.h"
|
||||||
|
#elif defined(HAVE_SSE4_1)
|
||||||
|
#include "blake2s-load-sse41.h"
|
||||||
|
#else
|
||||||
|
#include "blake2s-load-sse2.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ROUND(r) \
|
||||||
|
LOAD_MSG_ ##r ##_1(buf1); \
|
||||||
|
G1(row1,row2,row3,row4,buf1); \
|
||||||
|
LOAD_MSG_ ##r ##_2(buf2); \
|
||||||
|
G2(row1,row2,row3,row4,buf2); \
|
||||||
|
DIAGONALIZE(row1,row2,row3,row4); \
|
||||||
|
LOAD_MSG_ ##r ##_3(buf3); \
|
||||||
|
G1(row1,row2,row3,row4,buf3); \
|
||||||
|
LOAD_MSG_ ##r ##_4(buf4); \
|
||||||
|
G2(row1,row2,row3,row4,buf4); \
|
||||||
|
UNDIAGONALIZE(row1,row2,row3,row4); \
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
43
src/blake2s-test.c
Normal file
43
src/blake2s-test.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "blake2.h"
|
||||||
|
#include "blake2-kat.h"
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
uint8_t key[BLAKE2S_KEYBYTES];
|
||||||
|
uint8_t buf[KAT_LENGTH];
|
||||||
|
|
||||||
|
for( size_t i = 0; i < BLAKE2S_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[BLAKE2S_OUTBYTES];
|
||||||
|
|
||||||
|
if( blake2s( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
|
||||||
|
0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||||
|
{
|
||||||
|
puts( "error" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts( "ok" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
418
src/blake2s.c
Normal file
418
src/blake2s.c
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
#include "blake2-config.h"
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SSE2)
|
||||||
|
#include <emmintrin.h>
|
||||||
|
// MSVC only defines _mm_set_epi64x for x86_64...
|
||||||
|
#if defined(_MSC_VER) && !defined(_M_X64)
|
||||||
|
static inline __m128i _mm_set_epi64x( const uint64_t u1, const uint64_t u0 )
|
||||||
|
{
|
||||||
|
return _mm_set_epi32( u1 >> 32, u1, u0 >> 32, u0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(HAVE_SSSE3)
|
||||||
|
#include <tmmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_SSE4_1)
|
||||||
|
#include <smmintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_AVX)
|
||||||
|
#include <immintrin.h>
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_XOP) && !defined(_MSC_VER)
|
||||||
|
#include <x86intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "blake2s-round.h"
|
||||||
|
|
||||||
|
static const uint32_t blake2s_IV[8] =
|
||||||
|
{
|
||||||
|
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
|
||||||
|
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t blake2s_sigma[10][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 } ,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Some helper functions, not necessarily useful */
|
||||||
|
static inline int blake2s_set_lastnode( blake2s_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = ~0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_clear_lastnode( blake2s_state *S )
|
||||||
|
{
|
||||||
|
S->f[1] = 0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_set_lastblock( blake2s_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2s_set_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = ~0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_clear_lastblock( blake2s_state *S )
|
||||||
|
{
|
||||||
|
if( S->last_node ) blake2s_clear_lastnode( S );
|
||||||
|
|
||||||
|
S->f[0] = 0U;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_increment_counter( blake2s_state *S, const uint32_t inc )
|
||||||
|
{
|
||||||
|
uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0];
|
||||||
|
t += inc;
|
||||||
|
S->t[0] = ( uint32_t )( t >> 0 );
|
||||||
|
S->t[1] = ( uint32_t )( t >> 32 );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parameter-related functions
|
||||||
|
static inline int blake2s_param_set_digest_length( blake2s_param *P, const uint8_t digest_length )
|
||||||
|
{
|
||||||
|
P->digest_length = digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_fanout( blake2s_param *P, const uint8_t fanout )
|
||||||
|
{
|
||||||
|
P->fanout = fanout;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_max_depth( blake2s_param *P, const uint8_t depth )
|
||||||
|
{
|
||||||
|
P->depth = depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_leaf_length( blake2s_param *P, const uint32_t leaf_length )
|
||||||
|
{
|
||||||
|
P->leaf_length = leaf_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_node_offset( blake2s_param *P, const uint64_t node_offset )
|
||||||
|
{
|
||||||
|
store48( P->node_offset, node_offset );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_node_depth( blake2s_param *P, const uint8_t node_depth )
|
||||||
|
{
|
||||||
|
P->node_depth = node_depth;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_inner_length( blake2s_param *P, const uint8_t inner_length )
|
||||||
|
{
|
||||||
|
P->inner_length = inner_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_salt( blake2s_param *P, const uint8_t salt[BLAKE2S_SALTBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->salt, salt, BLAKE2S_SALTBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_param_set_personal( blake2s_param *P, const uint8_t personal[BLAKE2S_PERSONALBYTES] )
|
||||||
|
{
|
||||||
|
memcpy( P->personal, personal, BLAKE2S_PERSONALBYTES );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int blake2s_init0( blake2s_state *S )
|
||||||
|
{
|
||||||
|
memset( S, 0, sizeof( blake2s_state ) );
|
||||||
|
|
||||||
|
for( int i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define blake2s_init BLAKE2_IMPL_NAME(blake2s_init)
|
||||||
|
#define blake2s_init_param BLAKE2_IMPL_NAME(blake2s_init_param)
|
||||||
|
#define blake2s_init_key BLAKE2_IMPL_NAME(blake2s_init_key)
|
||||||
|
#define blake2s_update BLAKE2_IMPL_NAME(blake2s_update)
|
||||||
|
#define blake2s_final BLAKE2_IMPL_NAME(blake2s_final)
|
||||||
|
#define blake2s BLAKE2_IMPL_NAME(blake2s)
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
int blake2s_init( blake2s_state *S, size_t outlen );
|
||||||
|
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
|
||||||
|
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
|
||||||
|
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen );
|
||||||
|
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen );
|
||||||
|
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen );
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* init2 xors IV with input parameter block */
|
||||||
|
int blake2s_init_param( blake2s_state *S, const blake2s_param *P )
|
||||||
|
{
|
||||||
|
uint8_t *p, *h, *v;
|
||||||
|
//blake2s_init0( S );
|
||||||
|
v = ( uint8_t * )( blake2s_IV );
|
||||||
|
h = ( uint8_t * )( S->h );
|
||||||
|
p = ( uint8_t * )( P );
|
||||||
|
/* IV XOR ParamBlock */
|
||||||
|
memset( S, 0, sizeof( blake2s_state ) );
|
||||||
|
|
||||||
|
for( int i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i];
|
||||||
|
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Some sort of default parameter block initialization, for sequential blake2s */
|
||||||
|
int blake2s_init( blake2s_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
const blake2s_param P =
|
||||||
|
{
|
||||||
|
outlen,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
{0},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{0},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
return blake2s_init_param( S, &P );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1;
|
||||||
|
|
||||||
|
if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
const blake2s_param P =
|
||||||
|
{
|
||||||
|
outlen,
|
||||||
|
keylen,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
{0},
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{0},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
if( blake2s_init_param( S, &P ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
blake2s_update( S, block, BLAKE2S_BLOCKBYTES );
|
||||||
|
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] )
|
||||||
|
{
|
||||||
|
__m128i row1, row2, row3, row4;
|
||||||
|
__m128i buf1, buf2, buf3, buf4;
|
||||||
|
#if defined(HAVE_SSE4_1)
|
||||||
|
__m128i t0, t1;
|
||||||
|
#if !defined(HAVE_XOP)
|
||||||
|
__m128i t2;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
__m128i ff0, ff1;
|
||||||
|
#if defined(HAVE_SSSE3) && !defined(HAVE_XOP)
|
||||||
|
const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
|
||||||
|
const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_SSE4_1)
|
||||||
|
const __m128i m0 = LOADU( block + 00 );
|
||||||
|
const __m128i m1 = LOADU( block + 16 );
|
||||||
|
const __m128i m2 = LOADU( block + 32 );
|
||||||
|
const __m128i m3 = LOADU( block + 48 );
|
||||||
|
#else
|
||||||
|
const uint32_t m0 = ( ( uint32_t * )block )[ 0];
|
||||||
|
const uint32_t m1 = ( ( uint32_t * )block )[ 1];
|
||||||
|
const uint32_t m2 = ( ( uint32_t * )block )[ 2];
|
||||||
|
const uint32_t m3 = ( ( uint32_t * )block )[ 3];
|
||||||
|
const uint32_t m4 = ( ( uint32_t * )block )[ 4];
|
||||||
|
const uint32_t m5 = ( ( uint32_t * )block )[ 5];
|
||||||
|
const uint32_t m6 = ( ( uint32_t * )block )[ 6];
|
||||||
|
const uint32_t m7 = ( ( uint32_t * )block )[ 7];
|
||||||
|
const uint32_t m8 = ( ( uint32_t * )block )[ 8];
|
||||||
|
const uint32_t m9 = ( ( uint32_t * )block )[ 9];
|
||||||
|
const uint32_t m10 = ( ( uint32_t * )block )[10];
|
||||||
|
const uint32_t m11 = ( ( uint32_t * )block )[11];
|
||||||
|
const uint32_t m12 = ( ( uint32_t * )block )[12];
|
||||||
|
const uint32_t m13 = ( ( uint32_t * )block )[13];
|
||||||
|
const uint32_t m14 = ( ( uint32_t * )block )[14];
|
||||||
|
const uint32_t m15 = ( ( uint32_t * )block )[15];
|
||||||
|
#endif
|
||||||
|
row1 = ff0 = LOADU( &S->h[0] );
|
||||||
|
row2 = ff1 = LOADU( &S->h[4] );
|
||||||
|
row3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
|
||||||
|
row4 = _mm_xor_si128( _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ), LOADU( &S->t[0] ) );
|
||||||
|
ROUND( 0 );
|
||||||
|
ROUND( 1 );
|
||||||
|
ROUND( 2 );
|
||||||
|
ROUND( 3 );
|
||||||
|
ROUND( 4 );
|
||||||
|
ROUND( 5 );
|
||||||
|
ROUND( 6 );
|
||||||
|
ROUND( 7 );
|
||||||
|
ROUND( 8 );
|
||||||
|
ROUND( 9 );
|
||||||
|
STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) );
|
||||||
|
STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2s_update( blake2s_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
while( inlen > 0 )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen;
|
||||||
|
size_t fill = 2 * BLAKE2S_BLOCKBYTES - left;
|
||||||
|
|
||||||
|
if( inlen > fill )
|
||||||
|
{
|
||||||
|
memcpy( S->buf + left, in, fill ); // Fill buffer
|
||||||
|
S->buflen += fill;
|
||||||
|
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||||
|
blake2s_compress( S, S->buf ); // Compress
|
||||||
|
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); // Shift buffer left
|
||||||
|
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||||
|
in += fill;
|
||||||
|
inlen -= fill;
|
||||||
|
}
|
||||||
|
else /* inlen <= fill */
|
||||||
|
{
|
||||||
|
memcpy( S->buf + left, in, inlen );
|
||||||
|
S->buflen += inlen; // Be lazy, do not compress
|
||||||
|
in += inlen;
|
||||||
|
inlen -= inlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2s_final( blake2s_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
uint8_t buffer[BLAKE2S_OUTBYTES];
|
||||||
|
|
||||||
|
if(outlen != S->outlen ) return -1;
|
||||||
|
|
||||||
|
if( S->buflen > BLAKE2S_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES );
|
||||||
|
blake2s_compress( S, S->buf );
|
||||||
|
S->buflen -= BLAKE2S_BLOCKBYTES;
|
||||||
|
memcpy( S->buf, S->buf + BLAKE2S_BLOCKBYTES, S->buflen );
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2s_increment_counter( S, ( uint32_t )S->buflen );
|
||||||
|
blake2s_set_lastblock( S );
|
||||||
|
memset( S->buf + S->buflen, 0, 2 * BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */
|
||||||
|
blake2s_compress( S, S->buf );
|
||||||
|
|
||||||
|
for( int i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
|
||||||
|
store32( buffer + sizeof( S->h[i] ) * i, S->h[i] );
|
||||||
|
|
||||||
|
memcpy( out, buffer, outlen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2s( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
blake2s_state S[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == key && keylen > 0) return -1;
|
||||||
|
|
||||||
|
if( keylen > 0 )
|
||||||
|
{
|
||||||
|
if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( blake2s_init( S, outlen ) < 0 ) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blake2s_update( S, ( uint8_t * )in, inlen ) < 0) return -1;
|
||||||
|
return blake2s_final( S, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(SUPERCOP)
|
||||||
|
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
|
||||||
|
{
|
||||||
|
return blake2s( out, in, NULL, BLAKE2S_OUTBYTES, (size_t)inlen, 0 );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
43
src/blake2sp-test.c
Normal file
43
src/blake2sp-test.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "blake2.h"
|
||||||
|
#include "blake2-kat.h"
|
||||||
|
|
||||||
|
int main( int argc, char **argv )
|
||||||
|
{
|
||||||
|
uint8_t key[BLAKE2S_KEYBYTES];
|
||||||
|
uint8_t buf[KAT_LENGTH];
|
||||||
|
|
||||||
|
for( size_t i = 0; i < BLAKE2S_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[BLAKE2S_OUTBYTES];
|
||||||
|
if( blake2sp( hash, buf, key, BLAKE2S_OUTBYTES, i, BLAKE2S_KEYBYTES ) < 0 ||
|
||||||
|
0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) )
|
||||||
|
{
|
||||||
|
puts( "error" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts( "ok" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
272
src/blake2sp.c
Normal file
272
src/blake2sp.c
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/*
|
||||||
|
BLAKE2 reference source code package - optimized 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
#include <omp.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "blake2.h"
|
||||||
|
#include "blake2-impl.h"
|
||||||
|
|
||||||
|
#define PARALLELISM_DEGREE 8
|
||||||
|
|
||||||
|
static int blake2sp_init_leaf( blake2s_state *S, uint8_t outlen, uint8_t keylen, uint64_t offset )
|
||||||
|
{
|
||||||
|
blake2s_param P[1];
|
||||||
|
P->digest_length = outlen;
|
||||||
|
P->key_length = keylen;
|
||||||
|
P->fanout = PARALLELISM_DEGREE;
|
||||||
|
P->depth = 2;
|
||||||
|
P->leaf_length = 0;
|
||||||
|
store48( P->node_offset, offset );
|
||||||
|
P->node_depth = 0;
|
||||||
|
P->inner_length = BLAKE2S_OUTBYTES;
|
||||||
|
memset( P->salt, 0, sizeof( P->salt ) );
|
||||||
|
memset( P->personal, 0, sizeof( P->personal ) );
|
||||||
|
blake2s_init_param( S, P );
|
||||||
|
S->outlen = P->inner_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int blake2sp_init_root( blake2s_state *S, uint8_t outlen, uint8_t keylen )
|
||||||
|
{
|
||||||
|
blake2s_param P[1];
|
||||||
|
P->digest_length = outlen;
|
||||||
|
P->key_length = keylen;
|
||||||
|
P->fanout = PARALLELISM_DEGREE;
|
||||||
|
P->depth = 2;
|
||||||
|
P->leaf_length = 0;
|
||||||
|
store48( P->node_offset, 0ULL );
|
||||||
|
P->node_depth = 1;
|
||||||
|
P->inner_length = BLAKE2S_OUTBYTES;
|
||||||
|
memset( P->salt, 0, sizeof( P->salt ) );
|
||||||
|
memset( P->personal, 0, sizeof( P->personal ) );
|
||||||
|
blake2s_init_param( S, P );
|
||||||
|
S->outlen = P->digest_length;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2sp_init( blake2sp_state *S, size_t outlen )
|
||||||
|
{
|
||||||
|
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
memset( S->buf, 0, sizeof( S->buf ) );
|
||||||
|
S->buflen = 0;
|
||||||
|
|
||||||
|
if( blake2sp_init_root( S->R, outlen, 0 ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1;
|
||||||
|
|
||||||
|
S->R->last_node = 1;
|
||||||
|
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||||
|
S->outlen = outlen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen )
|
||||||
|
{
|
||||||
|
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
memset( S->buf, 0, sizeof( S->buf ) );
|
||||||
|
S->buflen = 0;
|
||||||
|
|
||||||
|
if( blake2sp_init_root( S->R, outlen, keylen ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||||
|
|
||||||
|
S->R->last_node = 1;
|
||||||
|
S->S[PARALLELISM_DEGREE - 1]->last_node = 1;
|
||||||
|
S->outlen = outlen;
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES );
|
||||||
|
|
||||||
|
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2sp_update( blake2sp_state *S, const uint8_t *in, size_t inlen )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen;
|
||||||
|
size_t fill = sizeof( S->buf ) - left;
|
||||||
|
|
||||||
|
if( left && inlen >= fill )
|
||||||
|
{
|
||||||
|
memcpy( S->buf + left, in, fill );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES );
|
||||||
|
|
||||||
|
in += fill;
|
||||||
|
inlen -= fill;
|
||||||
|
left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
omp_set_num_threads(PARALLELISM_DEGREE);
|
||||||
|
#pragma omp parallel shared(S)
|
||||||
|
#else
|
||||||
|
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
size_t id__ = omp_get_thread_num();
|
||||||
|
#endif
|
||||||
|
size_t inlen__ = inlen;
|
||||||
|
const uint8_t *in__ = ( const uint8_t * )in;
|
||||||
|
in__ += id__ * BLAKE2S_BLOCKBYTES;
|
||||||
|
|
||||||
|
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
blake2s_update( S->S[id__], in__, BLAKE2S_BLOCKBYTES );
|
||||||
|
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||||
|
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES );
|
||||||
|
inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||||
|
|
||||||
|
if( inlen > 0 )
|
||||||
|
memcpy( S->buf + left, in, inlen );
|
||||||
|
|
||||||
|
S->buflen = left + inlen;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2sp_final( blake2sp_state *S, uint8_t *out, size_t outlen )
|
||||||
|
{
|
||||||
|
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||||
|
|
||||||
|
if(S->outlen != outlen) return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
{
|
||||||
|
if( S->buflen > i * BLAKE2S_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES;
|
||||||
|
|
||||||
|
if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES;
|
||||||
|
|
||||||
|
blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left );
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES );
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES );
|
||||||
|
|
||||||
|
blake2s_final( S->R, out, outlen );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int blake2sp( uint8_t *out, const void *in, const void *key, size_t outlen, size_t inlen, size_t keylen )
|
||||||
|
{
|
||||||
|
uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES];
|
||||||
|
blake2s_state S[PARALLELISM_DEGREE][1];
|
||||||
|
blake2s_state FS[1];
|
||||||
|
|
||||||
|
/* Verify parameters */
|
||||||
|
if ( NULL == in ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == out ) return -1;
|
||||||
|
|
||||||
|
if ( NULL == key && keylen > 0 ) return -1;
|
||||||
|
|
||||||
|
if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1;
|
||||||
|
|
||||||
|
if( keylen > BLAKE2S_KEYBYTES ) return -1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1;
|
||||||
|
|
||||||
|
S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node
|
||||||
|
|
||||||
|
if( keylen > 0 )
|
||||||
|
{
|
||||||
|
uint8_t block[BLAKE2S_BLOCKBYTES];
|
||||||
|
memset( block, 0, BLAKE2S_BLOCKBYTES );
|
||||||
|
memcpy( block, key, keylen );
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES );
|
||||||
|
|
||||||
|
secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
omp_set_num_threads(PARALLELISM_DEGREE);
|
||||||
|
#pragma omp parallel shared(S,hash)
|
||||||
|
#else
|
||||||
|
|
||||||
|
for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#if defined(_OPENMP)
|
||||||
|
size_t id__ = omp_get_thread_num();
|
||||||
|
#endif
|
||||||
|
size_t inlen__ = inlen;
|
||||||
|
const uint8_t *in__ = ( const uint8_t * )in;
|
||||||
|
in__ += id__ * BLAKE2S_BLOCKBYTES;
|
||||||
|
|
||||||
|
while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
blake2s_update( S[id__], in__, BLAKE2S_BLOCKBYTES );
|
||||||
|
in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||||
|
inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( inlen__ > id__ * BLAKE2S_BLOCKBYTES )
|
||||||
|
{
|
||||||
|
const size_t left = inlen__ - id__ * BLAKE2S_BLOCKBYTES;
|
||||||
|
const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES;
|
||||||
|
blake2s_update( S[id__], in__, len );
|
||||||
|
}
|
||||||
|
|
||||||
|
blake2s_final( S[id__], hash[id__], BLAKE2S_OUTBYTES );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( blake2sp_init_root( FS, outlen, keylen ) < 0 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FS->last_node = 1;
|
||||||
|
|
||||||
|
for( size_t i = 0; i < PARALLELISM_DEGREE; ++i )
|
||||||
|
blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES );
|
||||||
|
|
||||||
|
return blake2s_final( FS, out, outlen );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user