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 )