Crypt-Bear

 view release on metacpan or  search on metacpan

src/hash/ghash_pwr8.c  view on Meta::CPAN

/*
 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining 
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be 
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#define BR_POWER_ASM_MACROS   1
#include "inner.h"

/*
 * This is the GHASH implementation that leverages the POWER8 opcodes.
 */

#if BR_POWER8

/*
 * Some symbolic names for registers.
 *   HB0 = 16 bytes of value 0
 *   HB1 = 16 bytes of value 1
 *   HB2 = 16 bytes of value 2
 *   HB6 = 16 bytes of value 6
 *   HB7 = 16 bytes of value 7
 *   TT0, TT1 and TT2 are temporaries
 *
 * BSW holds the pattern for byteswapping 32-bit words; this is set only
 * on little-endian systems. XBSW is the same register with the +32 offset
 * for access with the VSX opcodes.
 */
#define HB0     0
#define HB1     1
#define HB2     2
#define HB6     3
#define HB7     4
#define TT0     5
#define TT1     6
#define TT2     7

#define BSW     8
#define XBSW   40

/*
 * Macro to initialise the constants.
 */
#define INIT \
		vxor(HB0, HB0, HB0) \
		vspltisb(HB1, 1) \
		vspltisb(HB2, 2) \
		vspltisb(HB6, 6) \
		vspltisb(HB7, 7) \
		INIT_BSW

/*
 * Fix endianness of a value after reading it or before writing it, if
 * necessary.
 */
#if BR_POWER8_LE
#define INIT_BSW         lxvw4x(XBSW, 0, %[idx2be])
#define FIX_ENDIAN(xx)   vperm(xx, xx, xx, BSW)
#else
#define INIT_BSW
#define FIX_ENDIAN(xx)
#endif

/*
 * Left-shift x0:x1 by one bit to the left. This is a corrective action
 * needed because GHASH is defined in full little-endian specification,
 * while the opcodes use full big-endian convention, so the 255-bit product
 * ends up one bit to the right.
 */
#define SL_256(x0, x1) \
		vsldoi(TT0, HB0, x1, 1) \
		vsl(x0, x0, HB1) \
		vsr(TT0, TT0, HB7) \
		vsl(x1, x1, HB1) \
		vxor(x0, x0, TT0)

/*
 * Reduce x0:x1 in GF(2^128), result in xd (register xd may be the same as
 * x0 or x1, or a different register). x0 and x1 are modified.
 */
#define REDUCE_F128(xd, x0, x1) \
		vxor(x0, x0, x1) \
		vsr(TT0, x1, HB1) \
		vsr(TT1, x1, HB2) \
		vsr(TT2, x1, HB7) \
		vxor(x0, x0, TT0) \
		vxor(TT1, TT1, TT2) \
		vxor(x0, x0, TT1) \
		vsldoi(x1, x1, HB0, 15) \
		vsl(TT1, x1, HB6) \
		vsl(TT2, x1, HB1) \
		vxor(x1, TT1, TT2) \
		vsr(TT0, x1, HB1) \
		vsr(TT1, x1, HB2) \
		vsr(TT2, x1, HB7) \
		vxor(x0, x0, x1) \
		vxor(x0, x0, TT0) \
		vxor(TT1, TT1, TT2) \
		vxor(xd, x0, TT1)

/* see bearssl_hash.h */
void



( run in 0.458 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )