Merge branch 'master' into hmqv

pull/263/head
Jeffrey Walton 2016-08-24 06:20:00 -04:00
commit 74d5f7ab39
5 changed files with 339 additions and 210 deletions

View File

@ -35,10 +35,11 @@ CLANG_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "clang")
INTEL_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "\(icc\)")
MACPORTS_COMPILER := $(shell $(CXX) --version 2>&1 | $(EGREP) -i -c "macports")
# Sun Studio 12.0 (0x0510) and 12.3 (0x0512)
SUNCC_120_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[0-9]|5\.[2-9]|6\.)")
SUNCC_122_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[1-9]|5\.[2-9]|6\.)")
SUNCC_123_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[2-9]|5\.[2-9]|6\.)")
# Sun Studio 12.0 provides SunCC 0x0510; and Sun Studio 12.3 provides SunCC 0x0512
SUNCC_510_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[0-9]|5\.[2-9]|6\.)")
SUNCC_511_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[1-9]|5\.[2-9]|6\.)")
SUNCC_512_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[2-9]|5\.[2-9]|6\.)")
SUNCC_513_OR_LATER := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: (Sun|Studio) .* (5\.1[3-9]|5\.[2-9]|6\.)")
HAS_SOLIB_VERSION := $(IS_LINUX)
@ -54,7 +55,7 @@ endif
# Base CXXFLAGS used if the user did not specify them
ifeq ($(SUN_COMPILER),1)
ifeq ($(SUNCC_123_OR_LATER),1)
ifeq ($(SUNCC_512_OR_LATER),1)
CXXFLAGS ?= -DNDEBUG -g3 -xO2
else
CXXFLAGS ?= -DNDEBUG -g -xO2
@ -284,9 +285,12 @@ endif
ifneq ($(SUN_COMPILER),0) # override flags for CC Sun C++ compiler
IS_64 := $(shell isainfo -b 2>/dev/null | grep -i -c "64")
ifeq ($(IS_64),1)
CXXFLAGS += -native -m64
CXXFLAGS += -m64
else ifeq ($(IS_64),0)
CXXFLAGS += -native -m32
CXXFLAGS += -m32
endif
ifneq ($(SUNCC_513_OR_LATER),0)
CXXFLAGS += -native
endif
# Add for non-i386
ifneq ($(IS_X86),1)
@ -295,7 +299,7 @@ endif
# Add to all Solaris
CXXFLAGS += -template=no%extdef
# Add to Sun Studio 12.2 and above
ifneq ($(SUNCC_122_OR_LATER),0)
ifneq ($(SUNCC_511_OR_LATER),0)
CXXFLAGS += -w -erroff=wvarhidemem -erroff=voidretw
endif
SUN_CC10_BUGGY := $(shell $(CXX) -V 2>&1 | $(EGREP) -c "CC: Sun .* 5\.10 .* (2009|2010/0[1-4])")
@ -304,7 +308,7 @@ ifneq ($(SUN_CC10_BUGGY),0)
# remove it if you get "already had a body defined" errors in vector.cc
CXXFLAGS += -DCRYPTOPP_INCLUDE_VECTOR_CC
endif
#ifneq ($SUNCC_123_OR_LATER),0)
#ifneq ($SUNCC_512_OR_LATER),0)
#CXXFLAGS += -xarch=aes -D__AES__=1 -xarch=no%sse4_1 -xarch=no%sse4_2
#endif
AR = $(CXX)

View File

@ -43,9 +43,12 @@ inline __m128i _mm_set_epi64x(const word64 a, const word64 b)
static void BLAKE2_CXX_Compress32(const byte* input, BLAKE2_State<word32, false>& state);
static void BLAKE2_CXX_Compress64(const byte* input, BLAKE2_State<word64, true>& state);
// Also see http://github.com/weidai11/cryptopp/issues/247 for singling out SunCC 5.12
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
static void BLAKE2_SSE2_Compress32(const byte* input, BLAKE2_State<word32, false>& state);
# if (__SUNPRO_CC != 0x5120)
static void BLAKE2_SSE2_Compress64(const byte* input, BLAKE2_State<word64, true>& state);
# endif
#endif
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE
@ -161,9 +164,11 @@ pfnCompress64 InitializeCompress64Fn()
else
#endif
#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
# if (__SUNPRO_CC != 0x5120)
if (HasSSE2())
return &BLAKE2_SSE2_Compress64;
else
# endif
#endif
#if CRYPTOPP_BOOL_NEON_INTRINSICS_AVAILABLE
if (HasNEON())
@ -1032,6 +1037,7 @@ static void BLAKE2_SSE2_Compress32(const byte* input, BLAKE2_State<word32, false
_mm_storeu_si128((__m128i *)(void*)(&state.h[4]),_mm_xor_si128(ff1,_mm_xor_si128(row2,row4)));
}
# if (__SUNPRO_CC != 0x5120)
static void BLAKE2_SSE2_Compress64(const byte* input, BLAKE2_State<word64, true>& state)
{
word64 m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15;
@ -1916,6 +1922,7 @@ static void BLAKE2_SSE2_Compress64(const byte* input, BLAKE2_State<word64, true>
_mm_storeu_si128((__m128i *)(void*)(&state.h[4]), _mm_xor_si128(_mm_loadu_si128((const __m128i*)(const void*)(&state.h[4])), row2l));
_mm_storeu_si128((__m128i *)(void*)(&state.h[6]), _mm_xor_si128(_mm_loadu_si128((const __m128i*)(const void*)(&state.h[6])), row2h));
}
# endif // (__SUNPRO_CC != 0x5120)
#endif // CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE
#if CRYPTOPP_BOOL_SSE4_INTRINSICS_AVAILABLE

View File

@ -72,6 +72,8 @@ GREP=grep
EGREP=egrep
SED=sed
AWK=awk
DISASS=objdump
DISASSARGS=("--disassemble")
THIS_SYSTEM=$(uname -s 2>&1)
IS_DARWIN=$(echo "$THIS_SYSTEM" | "$GREP" -i -c darwin)
@ -115,6 +117,12 @@ if [[ "$IS_SOLARIS" -ne "0" ]]; then
fi
fi
# Fixup
if [[ "$IS_DARWIN" -ne 0 ]]; then
DISASS=otool
DISASSARGS=("-tV")
fi
for ARG in "$@"
do
# Recognize "fast" and "quick", which does not perform tests that take more time to execute
@ -174,6 +182,7 @@ if [[ ("$SUN_COMPILER" -eq "0") ]]; then
fi
# Now that the compiler is fixed, determine the compiler version for fixups
CLANG_37_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'clang version (3\.[7-9]|[5-9])')
GCC_60_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (6\.[0-9]|[7-9])')
GCC_51_OR_ABOVE=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version (5\.[1-9]|[6-9])')
GCC_48_COMPILER=$("$CXX" -v 2>&1 | "$EGREP" -i -c 'gcc version 4\.8')
@ -376,7 +385,7 @@ if [[ (-z "$HAVE_OS") ]]; then
"$CXX" -DCRYPTOPP_ADHOC_MAIN -Os adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1
if [[ ("$?" -eq "0") ]]; then
HAVE_OS=1
HAVE_OS=-Os
OPT_OS=-Os
fi
fi
@ -558,25 +567,20 @@ if [[ (-z "$HAVE_UNIFIED_ASM") ]]; then
fi
fi
# Aarch32 on Aarch64
if [[ (-z "$HAVE_AARCH32") ]]; then
HAVE_AARCH32=0
rm -f "$TMP/adhoc.exe" > /dev/null 2>&1
"$CXX" -DCRYPTOPP_ADHOC_MAIN -march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 adhoc.cpp -o "$TMP/adhoc.exe" > /dev/null 2>&1
if [[ "$?" -eq "0" ]]; then
HAVE_AARCH32=1
fi
fi
# ARMv7 and ARMv8, including NEON, CRC32 and Crypto extensions
if [[ ("$IS_ARM32" -ne "0" || "$IS_ARM64" -ne "0") ]]; then
ARM_FEATURES=$(cat /proc/cpuinfo 2>&1 | "$AWK" '{IGNORECASE=1}{if ($1 == "Features") print}' | cut -f 2 -d ':')
if [[ (-z "$HAVE_ARMV7A" && "$IS_ARM32" -ne "0") ]]; then
if [[ (-z "$HAVE_ARMV7A" && "$IS_ARM32" -ne "0") ]]; then
HAVE_ARMV7A=$(echo "$ARM_FEATURES" | "$GREP" -i -c 'neon')
if [[ ("$HAVE_ARMV7A" -gt "0") ]]; then HAVE_ARMV7A=1; fi
fi
if [[ (-z "$HAVE_ARMV8A" && ("$IS_ARM32" -ne "0" || "$IS_ARM64" -ne "0")) ]]; then
HAVE_ARMV8A=$(echo "$ARM_FEATURES" | "$EGREP" -i -c '(asimd|crc|crypto)')
if [[ ("$HAVE_ARMV8A" -gt "0") ]]; then HAVE_ARMV8A=1; fi
fi
if [[ (-z "$HAVE_ARM_VFPV3") ]]; then
HAVE_ARM_VFPV3=$(echo "$ARM_FEATURES" | "$GREP" -i -c 'vfpv3')
if [[ ("$HAVE_ARM_VFPV3" -gt "0") ]]; then HAVE_ARM_VFPV3=1; fi
@ -602,7 +606,7 @@ if [[ ("$IS_ARM32" -ne "0" || "$IS_ARM64" -ne "0") ]]; then
if [[ ("$HAVE_ARM_NEON" -gt "0") ]]; then HAVE_ARM_NEON=1; fi
fi
if [[ (-z "$HAVE_ARMV8") ]]; then
if [[ (-z "$HAVE_ARMV8A") ]]; then
HAVE_ARMV8="$IS_ARM64"
fi
@ -642,9 +646,9 @@ fi
# Used to disassemble object modules so we can verify some aspects of code generation
if [[ (-z "$HAVE_DISASS") ]]; then
echo "int main(int argc, char* argv[]) {return 0;}" > "$TMP/test.cc"
gcc "$TMP/test.cc" -o "$TMP/test.exe" > /dev/null 2>&1
"$CXX" -x c "$TMP/test.cc" -o "$TMP/test.exe" > /dev/null 2>&1
if [[ "$?" -eq "0" ]]; then
gdb -batch -ex 'disassemble main' "$TMP/test.exe" > /dev/null 2>&1
"$DISASS" "${DISASSARGS[@]}" "$TMP/test.exe" > /dev/null 2>&1
if [[ "$?" -eq "0" ]]; then
HAVE_DISASS=1
else
@ -694,13 +698,8 @@ if [[ "$IS_ARM64" -ne "0" ]]; then
elif [[ "$IS_ARM32" -ne "0" ]]; then
echo "IS_ARM32: $IS_ARM32" | tee -a "$TEST_RESULTS"
fi
if [[ "$HAVE_AARCH32" -ne "0" ]]; then
echo "HAVE_AARCH32: $HAVE_AARCH32" | tee -a "$TEST_RESULTS"
fi
if [[ "$HAVE_ARMV7A" -ne "0" ]]; then
echo "HAVE_ARMV7A: $HAVE_ARMV7A" | tee -a "$TEST_RESULTS"
elif [[ "$HAVE_ARMV8" -ne "0" ]]; then
echo "HAVE_ARMV8: $HAVE_ARMV8" | tee -a "$TEST_RESULTS"
elif [[ "$HAVE_ARMV8A" -ne "0" ]]; then
echo "HAVE_ARMV8A: $HAVE_ARMV8A" | tee -a "$TEST_RESULTS"
fi
@ -886,19 +885,17 @@ fi
# Please, someone put an end to the madness of determining Features, ABI, hard floats and soft floats...
if [[ ("$IS_ARM32" -ne "0" || "$IS_ARM64" -ne "0") ]]; then
# Add to exercise ARMv7, ARMv7-a, VFPU and NEON more thoroughly
if [[ ("$IS_ARM32" -ne "0") ]]; then
if [[ ("$HAVE_ARMV7A" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-march=armv7-a")
else
PLATFORM_CXXFLAGS+=("-march=armv7")
fi
if [[ (("$HAVE_ARMV7A" -ne "0") && ("$IS_ARM32" -ne "0")) ]]; then
PLATFORM_CXXFLAGS+=("-march=armv7-a")
# http://community.arm.com/groups/tools/blog/2013/04/15/arm-cortex-a-processors-and-gcc-command-lines
# These may need more tuning. If it was easy to get the CPU brand name, like Cortex-A9, then we could
# These may need more tuning. If it was easy to get the CPU model, like Cortex-A9, then we could
# be fairly certain of the FPU and ABI flags. But we can't easily get a CPU name, so we suffer through it.
# Also see http://lists.linaro.org/pipermail/linaro-toolchain/2016-July/005821.html
if [[ ("$HAVE_ARM_NEON" -ne "0" && "$HAVE_ARM_VFPV4" -ne "0") ]]; then
if [[ ("$HAVE_ARM_NEON" -ne "0" && "$CLANG_COMPILER" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfpu=neon")
elif [[ ("$HAVE_ARM_NEON" -ne "0" && "$HAVE_ARM_VFPV4" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfpu=neon-vfpv4")
elif [[ ("$HAVE_ARM_NEON" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfpu=neon")
@ -918,27 +915,44 @@ if [[ ("$IS_ARM32" -ne "0" || "$IS_ARM64" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfpu=vfpv3-d16")
fi
# Soft/Hard floats only apply to 32-bit ARM
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16242.html
ARM_HARD_FLOAT=$("$CXX" -v 2>&1 | "$GREP" 'Target' | "$EGREP" -i -c '(armhf|gnueabihf)')
if [[ ("$ARM_HARD_FLOAT" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfloat-abi=hard")
else
PLATFORM_CXXFLAGS+=("-mfloat-abi=softfp")
fi
fi
elif [[ (("$HAVE_ARMV8A" -ne "0") && ("$IS_ARM64" -ne "0")) ]]; then
# Add to exercise ARMv8 more thoroughly. NEON is baked into the CPU asimd flag.
if [[ ("$IS_ARM64" -ne "0") ]]; then
if [[ ("$HAVE_ARM_CRC" -ne "0" && "$HAVE_ARM_CRYPTO" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-march=armv8-a+crc+crypto")
elif [[ ("$HAVE_ARM_CRC" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-march=armv8-a+crc")
elif [[ ("$HAVE_ARM_CRYPTO" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-march=armv8-a+crypto")
elif [[ ("$HAVE_ARMV8" -ne "0") ]]; then
else
PLATFORM_CXXFLAGS+=("-march=armv8-a")
fi
elif [[ (("$HAVE_ARMV8A" -ne "0") && ("$IS_ARM32" -ne "0")) ]]; then
if [[ ("$HAVE_ARM_CRC" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-march=armv8-a+crc")
else
PLATFORM_CXXFLAGS+=("-march=armv8-a")
fi
if [[ ("$CLANG_COMPILER" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfpu=neon")
elif [[ ("$HAVE_ARM_CRYPTO" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfpu=crypto-neon-fp-armv8")
else
PLATFORM_CXXFLAGS+=("-mfpu=neon-fp-armv8")
fi
fi
# Soft/Hard floats only apply to 32-bit ARM
# http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16242.html
if [[ ("$IS_ARM32" -ne "0") ]]; then
ARM_HARD_FLOAT=$("$CXX" -v 2>&1 | "$GREP" 'Target' | "$EGREP" -i -c '(armhf|gnueabihf)')
if [[ ("$ARM_HARD_FLOAT" -ne "0") ]]; then
PLATFORM_CXXFLAGS+=("-mfloat-abi=hard")
else
PLATFORM_CXXFLAGS+=("-mfloat-abi=softfp")
fi
fi
fi
@ -1000,7 +1014,7 @@ echo "Start time: $TEST_BEGIN" | tee -a "$TEST_RESULTS"
############################################
# Test AES-NI code generation
if [[ ("$HAVE_DISASS" -ne "0" && "$HAVE_X86_AES" -ne "0") ]] && false; then
if [[ ("$HAVE_DISASS" -ne "0" && "$HAVE_X86_AES" -ne "0") ]]; then
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: AES-NI code generation" | tee -a "$TEST_RESULTS"
@ -1010,32 +1024,90 @@ if [[ ("$HAVE_DISASS" -ne "0" && "$HAVE_X86_AES" -ne "0") ]] && false; then
rm -f adhoc.cpp > /dev/null 2>&1
OBJFILE=rijndael.o
CXX="$CXX" CXXFLAGS="$RELEASE_CXXFLAGS -march=native -maes" $OBJFILE 2>&1 | tee -a "$TEST_RESULTS"
CXX="$CXX" CXXFLAGS="$RELEASE_CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" $OBJFILE 2>&1 | tee -a "$TEST_RESULTS"
MANGLED=($(nm $OBJFILE))
UNMANGLED=($(nm $OBJFILE | c++filt))
IDX=-1
COUNT=0
FAILED=0
DISASS_TEXT=$("$DISASS" "${DISASSARGS[@]}" "$OBJFILE" 2>/dev/null)
for i in "${!UNMANGLED[@]}"; do
if [[ "${UNMANGLED[$i]}" = "${value}" ]]; then
IDX="${i}";
fi
done
DISASS=$(gdb -batch -ex 'disassemble AESNI_Enc_Block AESNI_Enc_4_Blocks' $OBJFILE 2>/dev/null)
if [[ ($(echo "$DISASS" | grep -i aesenc) -eq "0") ]]; then
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c aesenc)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate aesenc instruction" | tee -a "$TEST_RESULTS"
fi
if [[ ($(echo "$DISASS" | grep -i aesenclast) -eq "0") ]]; then
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c aesenclast)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate aesenclast instruction" | tee -a "$TEST_RESULTS"
fi
if [[ ($(echo "$DISASS" | grep -i aesdec) -eq "0") ]]; then
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c aesdec)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate aesdec instruction" | tee -a "$TEST_RESULTS"
fi
if [[ ($(echo "$DISASS" | grep -i aesdeclast) -eq "0") ]]; then
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c aesdeclast)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate aesdeclast instruction" | tee -a "$TEST_RESULTS"
fi
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c aesimc)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate aesimc instruction" | tee -a "$TEST_RESULTS"
fi
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c aeskeygenassist)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate aeskeygenassist instruction" | tee -a "$TEST_RESULTS"
fi
if [[ ("$FAILED" -eq "0") ]];then
echo "Verified aesenc, aesenclast, aesdec, aesdeclast, aesimc, aeskeygenassist machine instruction generation" | tee -a "$TEST_RESULTS"
else
if [[ ("$CLANG_COMPILER" -ne "0" && "$CLANG_37_OR_ABOVE" -eq "0") ]]; then
echo "This could be due to Clang and lack of expected support for SSSE3 in some versions of the compiler. If so, try Clang 3.7 or above"
fi
fi
fi
############################################
# ARM 64x64→128-bit multiply code generation
if [[ ("$HAVE_DISASS" -ne "0" && "$HAVE_ARM_CRYPTO" -ne "0") ]]; then
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: ARM 64x64→128-bit multiply code generation" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
OBJFILE=gcm.o
CXX="$CXX" CXXFLAGS="$RELEASE_CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" $OBJFILE 2>&1 | tee -a "$TEST_RESULTS"
COUNT=0
FAILED=0
DISASS_TEXT=$("$DISASS" "${DISASSARGS[@]}" "$OBJFILE" 2>/dev/null)
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -v pmull2 | "$GREP" -i -c pmull)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate pmull instruction" | tee -a "$TEST_RESULTS"
fi
COUNT=$(echo "$DISASS_TEXT" | "$GREP" -i -c pmull2)
if [[ ("$COUNT" -eq "0") ]]; then
FAILED=1
echo "ERROR: failed to generate pmull2 instruction" | tee -a "$TEST_RESULTS"
fi
if [[ ("$FAILED" -eq "0") ]];then
echo "Verified pmull and pmull2 machine instruction generation" | tee -a "$TEST_RESULTS"
fi
fi
############################################
@ -2273,7 +2345,7 @@ if [[ "$HAVE_OS" -ne "0" ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="-DDEBUG $OPT_OS ${PLATFORM_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXXFLAGS="-DDEBUG $OPT_OS -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS ${PLATFORM_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
@ -2299,7 +2371,7 @@ if [[ "$HAVE_OS" -ne "0" ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="-DNDEBUG $OPT_OS ${PLATFORM_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXXFLAGS="-DNDEBUG $OPT_OS -DCRYPTOPP_NO_UNALIGNED_DATA_ACCESS ${PLATFORM_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
@ -2862,71 +2934,6 @@ if [[ ("$HAVE_CXX17" -ne "0" && "$HAVE_ASAN" -ne "0") ]]; then
fi
fi
############################################
# Aarch32 on Aarch64
if [[ ("$HAVE_AARCH32" -ne "0") ]]; then
AARCH32_CXXFLAGS=("-march=armv8-a+crc" "-mtune=cortex-a53" "-mfpu=crypto-neon-fp-armv8")
ARM_HARD_FLOAT=$("$CXX" -v 2>&1 | "$GREP" 'Target' | "$EGREP" -i -c '(armhf|gnueabihf)')
if [[ "$ARM_HARD_FLOAT" -ne "0" ]]; then
AARCH32_CXXFLAGS+=("-mfloat-abi=hard")
else
AARCH32_CXXFLAGS+=("-mfloat-abi=softfp")
fi
############################################
# Debug build, Aarch32 on Aarch64
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: Debug, Aarch32 on Aarch64" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$DEBUG_CXXFLAGS ${AARCH32_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS"
fi
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS"
fi
fi
############################################
# Release build, Aarch32 on Aarch64
echo
echo "************************************" | tee -a "$TEST_RESULTS"
echo "Testing: Release, Aarch32 on Aarch64" | tee -a "$TEST_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$RELEASE_CXXFLAGS ${AARCH32_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS"
fi
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS"
fi
fi
fi
# For Solaris, test under Sun Studio 12.2 - 12.5
if [[ "$IS_SOLARIS" -ne "0" ]]; then
@ -2936,7 +2943,7 @@ if [[ "$IS_SOLARIS" -ne "0" ]]; then
fi
# Sun Studio 12.3 and below workaround, http://github.com/weidai11/cryptopp/issues/228
SUNCC_SSE_CXXFLAGS=$(echo "$SUNCC_CXXFLAGS" | "$AWK" '/SSE/' ORS=' ' RS=' ')
SUNCC_SSE_CXXFLAGS=$(echo -n "${SUNCC_CXXFLAGS[@]}" | "$AWK" '/SSE/' ORS=' ' RS=' ')
############################################
# Sun Studio 12.2
@ -2952,8 +2959,8 @@ if [[ "$IS_SOLARIS" -ne "0" ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="-DDEBUG -g -xO0 $SUNCC_SSE_CXXFLAGS"
CXX=/opt/solstudio12.2/bin/CC CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
CXXFLAGS="-DDEBUG -g -xO0 ${SUNCC_SSE_CXXFLAGS[@]}"
CXX="/opt/solstudio12.2/bin/CC" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
@ -2978,8 +2985,8 @@ if [[ "$IS_SOLARIS" -ne "0" ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="-DNDEBUG -g0 -xO2 $SUNCC_SSE_CXXFLAGS"
CXX=/opt/solstudio12.2/bin/CC CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
CXXFLAGS="-DNDEBUG -g -xO2 ${SUNCC_SSE_CXXFLAGS[@]}"
CXX="/opt/solstudio12.2/bin/CC" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
@ -4102,7 +4109,7 @@ if [[ ("$HAVE_CXX11" -ne "0" && ("$HAVE_GCC" -ne "0" || "$HAVE_CLANG" -ne "0"))
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$DEBUG_CXXFLAGS -std=c++11 ${DEPRECATED_CXXFLAGS[@]} ${ELEVATED_CXXFLAGS[@]}"
CXXFLAGS="$DEBUG_CXXFLAGS -std=c++11 ${DEPRECATED_CXXFLAGS[@]} ${ELEVATED_CXXFLAGS[@]}"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$WARN_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
@ -4222,7 +4229,8 @@ if [[ ("$CLANG_COMPILER" -eq "0") ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXX="$CLANG_CXX" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
CXXFLAGS="-DNDEBUG -g2 -O2 ${DEPRECATED_CXXFLAGS[@]}"
CXX="$CLANG_CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
@ -4256,7 +4264,8 @@ if [[ ("$GCC_COMPILER" -eq "0") ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXX="$GCC_CXX" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
CXXFLAGS="-DNDEBUG -g2 -O2 ${DEPRECATED_CXXFLAGS[@]}"
CXX="$GCC_CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
@ -4293,6 +4302,7 @@ if [[ ("$INTEL_COMPILER" -eq "0") ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="-DNDEBUG -g2 -O2 ${DEPRECATED_CXXFLAGS[@]}"
CXX="$INTEL_CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
@ -4328,7 +4338,8 @@ if [[ ("$MACPORTS_COMPILER" -eq "0") ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXX="$MACPORTS_CXX" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
CXXFLAGS="-DNDEBUG -g2 -O2 ${DEPRECATED_CXXFLAGS[@]}"
CXX="$MACPORTS_CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
@ -4359,7 +4370,8 @@ if [[ ("$MACPORTS_COMPILER" -eq "0") ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXX="$MACPORTS_CXX" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
CXXFLAGS="-DNDEBUG -g2 -O2 ${DEPRECATED_CXXFLAGS[@]}"
CXX="$MACPORTS_CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS"
else
@ -4393,7 +4405,7 @@ if [[ "$IS_DARWIN" -ne "0" ]]; then
"$MAKE" clean > /dev/null 2>&1
rm -f adhoc.cpp > /dev/null 2>&1
CXXFLAGS="$RELEASE_CXXFLAGS ${PLATFORM_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXXFLAGS="-DNDEBUG -g2 -O2 ${DEPRECATED_CXXFLAGS[@]}"
CXX="$XCODE_CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static cryptest.exe 2>&1 | tee -a "$TEST_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
@ -4416,8 +4428,8 @@ fi
if [[ ("$IS_CYGWIN" -eq "0") && ("$IS_MINGW" -eq "0") ]]; then
echo
echo "************************************" | tee -a "$INSTALL_RESULTS"
echo "Testing: Test install with data directory" | tee -a "$INSTALL_RESULTS"
echo "************************************" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo "Testing: Test install with data directory" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo
"$MAKE" clean > /dev/null 2>&1
@ -4427,52 +4439,51 @@ if [[ ("$IS_CYGWIN" -eq "0") && ("$IS_MINGW" -eq "0") ]]; then
rm -rf "$INSTALL_DIR" > /dev/null 2>&1
CXXFLAGS="$RELEASE_CXXFLAGS -DCRYPTOPP_DATA_DIR='\"$INSTALL_DIR/share/cryptopp/\"' ${PLATFORM_CXXFLAGS[@]} $USER_CXXFLAGS ${DEPRECATED_CXXFLAGS[@]}"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$INSTALL_RESULTS"
CXX="$CXX" CXXFLAGS="$CXXFLAGS" "$MAKE" "${MAKEARGS[@]}" static dynamic cryptest.exe 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make cryptest.exe" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to make cryptest.exe" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
else
# Still need to manulally place TestData and TestVectors
OLD_DIR=$(pwd)
"$MAKE" "${MAKEARGS[@]}" install PREFIX="$INSTALL_DIR" 2>&1 | tee -a "$INSTALL_RESULTS"
"$MAKE" "${MAKEARGS[@]}" install PREFIX="$INSTALL_DIR" 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
cd "$INSTALL_DIR/bin"
echo
echo "************************************" | tee -a "$INSTALL_RESULTS"
echo "Testing: Install (validation suite)" | tee -a "$INSTALL_RESULTS"
echo "************************************" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo "Testing: Install (validation suite)" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo
./cryptest.exe v 2>&1 | tee -a "$INSTALL_RESULTS"
./cryptest.exe v 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute validation suite" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to execute validation suite" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
echo
echo "************************************" | tee -a "$INSTALL_RESULTS"
echo "Testing: Install (test vectors)" | tee -a "$INSTALL_RESULTS"
echo "************************************" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo "Testing: Install (test vectors)" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo
./cryptest.exe tv all 2>&1 | tee -a "$INSTALL_RESULTS"
./cryptest.exe tv all 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute test vectors" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to execute test vectors" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ "$WANT_BENCHMARKS" -ne "0" ]]; then
echo
echo "************************************" | tee -a "$INSTALL_RESULTS"
echo "Testing: Install (benchmarks)" | tee -a "$INSTALL_RESULTS"
echo "************************************" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo "Testing: Install (benchmarks)" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo
./cryptest.exe b 1 2.4+1e9 2>&1 | tee -a "$INSTALL_RESULTS"
./cryptest.exe b 1 2.4+1e9 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to execute benchmarks" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to execute benchmarks" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
fi
echo
echo "************************************" | tee -a "$INSTALL_RESULTS"
echo "Testing: Install (help file)" | tee -a "$INSTALL_RESULTS"
echo "************************************" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo "Testing: Install (help file)" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo
./cryptest.exe h 2>&1 | tee -a "$INSTALL_RESULTS"
./cryptest.exe h 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "1") ]]; then
echo "ERROR: failed to provide help" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to provide help" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
# Restore original PWD
@ -4485,37 +4496,37 @@ fi
if [[ ("$IS_CYGWIN" -eq "0" && "$IS_MINGW" -eq "0") ]]; then
echo
echo "************************************" | tee -a "$INSTALL_RESULTS"
echo "Testing: Test remove with data directory" | tee -a "$INSTALL_RESULTS"
echo "************************************" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo "Testing: Test remove with data directory" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
echo
"$MAKE" "${MAKEARGS[@]}" remove PREFIX="$INSTALL_DIR" 2>&1 | tee -a "$INSTALL_RESULTS"
"$MAKE" "${MAKEARGS[@]}" remove PREFIX="$INSTALL_DIR" 2>&1 | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
if [[ ("${PIPESTATUS[0]}" -ne "0") ]]; then
echo "ERROR: failed to make remove" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to make remove" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
else
# Test for complete removal
if [[ (-d "$INSTALL_DIR/include/cryptopp") ]]; then
echo "ERROR: failed to remove cryptopp include directory" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove cryptopp include directory" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ (-d "$INSTALL_DIR/share/cryptopp") ]]; then
echo "ERROR: failed to remove cryptopp share directory" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove cryptopp share directory" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ (-d "$INSTALL_DIR/share/cryptopp/TestData") ]]; then
echo "ERROR: failed to remove cryptopp test data directory" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove cryptopp test data directory" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ (-d "$INSTALL_DIR/share/cryptopp/TestVector") ]]; then
echo "ERROR: failed to remove cryptopp test vector directory" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove cryptopp test vector directory" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ (-e "$INSTALL_DIR/bin/cryptest.exe") ]]; then
echo "ERROR: failed to remove cryptest.exe program" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove cryptest.exe program" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ (-e "$INSTALL_DIR/lib/libcryptopp.a") ]]; then
echo "ERROR: failed to remove libcryptopp.a static library" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove libcryptopp.a static library" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
if [[ "$IS_DARWIN" -ne "0" && (-e "$INSTALL_DIR/lib/libcryptopp.dylib") ]]; then
echo "ERROR: failed to remove libcryptopp.dylib dynamic library" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove libcryptopp.dylib dynamic library" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
elif [[ (-e "$INSTALL_DIR/lib/libcryptopp.so") ]]; then
echo "ERROR: failed to remove libcryptopp.so dynamic library" | tee -a "$INSTALL_RESULTS"
echo "ERROR: failed to remove libcryptopp.so dynamic library" | tee -a "$TEST_RESULTS" "$INSTALL_RESULTS"
fi
fi
fi

130
rw.cpp
View File

@ -7,9 +7,16 @@
#include "integer.h"
#include "nbtheory.h"
#include "modarith.h"
#include "asn.h"
#ifndef CRYPTOPP_IMPORTS
#if defined(_OPENMP)
static const bool CRYPTOPP_RW_USE_OMP = true;
#else
static const bool CRYPTOPP_RW_USE_OMP = false;
#endif
NAMESPACE_BEGIN(CryptoPP)
void RWFunction::BERDecode(BufferedTransformation &bt)
@ -103,6 +110,55 @@ void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const Name
m_n = m_p * m_q;
m_u = m_q.InverseMod(m_p);
Precompute();
}
void InvertibleRWFunction::Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u)
{
m_n = n; m_p = p; m_q = q; m_u = u;
Precompute();
}
void InvertibleRWFunction::PrecomputeTweakedRoots() const
{
ModularArithmetic modp(m_p), modq(m_q);
#pragma omp parallel sections if(CRYPTOPP_RW_USE_OMP)
{
#pragma omp section
m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8);
#pragma omp section
m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8);
#pragma omp section
m_pre_q_p = modp.Exponentiate(m_q, m_p - 2);
}
m_precompute = true;
}
void InvertibleRWFunction::LoadPrecomputation(BufferedTransformation &bt)
{
BERSequenceDecoder seq(bt);
m_pre_2_9p.BERDecode(seq);
m_pre_2_3q.BERDecode(seq);
m_pre_q_p.BERDecode(seq);
seq.MessageEnd();
m_precompute = true;
}
void InvertibleRWFunction::SavePrecomputation(BufferedTransformation &bt) const
{
if(!m_precompute)
Precompute();
DERSequenceEncoder seq(bt);
m_pre_2_9p.DEREncode(seq);
m_pre_2_3q.DEREncode(seq);
m_pre_q_p.DEREncode(seq);
seq.MessageEnd();
}
void InvertibleRWFunction::BERDecode(BufferedTransformation &bt)
@ -113,6 +169,8 @@ void InvertibleRWFunction::BERDecode(BufferedTransformation &bt)
m_q.BERDecode(seq);
m_u.BERDecode(seq);
seq.MessageEnd();
m_precompute = false;
}
void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const
@ -125,44 +183,70 @@ void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const
seq.MessageEnd();
}
// DJB's "RSA signatures and Rabin-Williams signatures..." (http://cr.yp.to/sigs/rwsota-20080131.pdf).
Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
{
DoQuickSanityCheck();
ModularArithmetic modn(m_n);
if(!m_precompute)
Precompute();
ModularArithmetic modn(m_n), modp(m_p), modq(m_q);
Integer r, rInv;
do {
// do this in a loop for people using small numbers for testing
do
{
// Do this in a loop for people using small numbers for testing
r.Randomize(rng, Integer::One(), m_n - Integer::One());
// Fix for CVE-2015-2141. Thanks to Evgeny Sidorov for reporting.
// Squaring to satisfy Jacobi requirements suggested by Jean-Pierre Münch.
// Squaring to satisfy Jacobi requirements suggested by Jean-Pierre Munch.
r = modn.Square(r);
rInv = modn.MultiplicativeInverse(r);
} while (rInv.IsZero());
Integer re = modn.Square(r);
re = modn.Multiply(re, x); // blind
re = modn.Multiply(re, x); // blind
Integer cp=re%m_p, cq=re%m_q;
if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1)
const Integer &h = re, &p = m_p, &q = m_q, &n = m_n;
Integer e, f;
const Integer U = modq.Exponentiate(h, (q+1)/8);
if(((modq.Exponentiate(U, 4) - h) % q).IsZero())
e = Integer::One();
else
e = -1;
const Integer eh = e*h, V = modp.Exponentiate(eh, (p-3)/8);
if(((modp.Multiply(modp.Exponentiate(V, 4), modp.Exponentiate(eh, 2)) - eh) % p).IsZero())
f = Integer::One();
else
f = 2;
Integer W, X;
#pragma omp parallel sections if(CRYPTOPP_RW_USE_OMP)
{
cp = cp.IsOdd() ? (cp+m_p) >> 1 : cp >> 1;
cq = cq.IsOdd() ? (cq+m_q) >> 1 : cq >> 1;
}
#pragma omp parallel
#pragma omp sections
#pragma omp section
{
#pragma omp section
cp = ModularSquareRoot(cp, m_p);
#pragma omp section
cq = ModularSquareRoot(cq, m_q);
W = (f.IsUnit() ? U : modq.Multiply(m_pre_2_3q, U));
}
#pragma omp section
{
const Integer t = modp.Multiply(modp.Exponentiate(V, 3), eh);
X = (f.IsUnit() ? t : modp.Multiply(m_pre_2_9p, t));
}
}
const Integer Y = W + q * modp.Multiply(m_pre_q_p, (X - W));
Integer y = CRT(cq, m_q, cp, m_p, m_u);
y = modn.Multiply(y, rInv); // unblind
y = STDMIN(y, m_n-y);
if (ApplyFunction(y) != x) // check
// Signature
Integer s = modn.Multiply(modn.Square(Y), rInv);
assert((e * f * s.Squared()) % m_n == x);
// IEEE P1363, Section 8.2.8 IFSP-RW, p.44
s = STDMIN(s, m_n - s);
if (ApplyFunction(s) != x) // check
throw Exception(Exception::OTHER_ERROR, "InvertibleRWFunction: computational error during private key operation");
return y;
return s;
}
bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
@ -197,6 +281,8 @@ void InvertibleRWFunction::AssignFrom(const NameValuePairs &source)
CRYPTOPP_SET_FUNCTION_ENTRY(Prime2)
CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1)
;
m_precompute = false;
}
NAMESPACE_END

39
rw.h
View File

@ -1,20 +1,24 @@
// rw.h - written and placed in the public domain by Wei Dai
//! \file rw.h
//! \brief Classes for Rabin-Williams signature schemes
//! \details Rabin-Williams signature schemes as defined in IEEE P1363.
//! \brief Classes for Rabin-Williams signature scheme
//! \details The implementation provides Rabin-Williams signature schemes as defined in
//! IEEE P1363. It uses Bernstein's tweaked square roots in place of square roots to
//! speedup calculations.
//! \sa <A HREF="http://cr.yp.to/sigs/rwsota-20080131.pdf">RSA signatures and RabinWilliams
//! signatures: the state of the art (20080131)</A>, Section 6, <em>The tweaks e and f</em>.
#ifndef CRYPTOPP_RW_H
#define CRYPTOPP_RW_H
#include "cryptlib.h"
#include "pubkey.h"
#include "integer.h"
NAMESPACE_BEGIN(CryptoPP)
//! _
//! \class RWFunction
//! \brief Rabin-Williams trapdoor function using the public key
class CRYPTOPP_DLL RWFunction : public TrapdoorFunction, public PublicKey
{
typedef RWFunction ThisClass;
@ -46,14 +50,16 @@ protected:
Integer m_n;
};
//! _
//! \class InvertibleRWFunction
//! \brief Rabin-Williams trapdoor function using the private key
class CRYPTOPP_DLL InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey
{
typedef InvertibleRWFunction ThisClass;
public:
void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u)
{m_n = n; m_p = p; m_q = q; m_u = u;}
InvertibleRWFunction() : m_precompute(false) {}
void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u);
// generate a random private key
void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits)
{GenerateRandomWithKeySize(rng, modulusBits);}
@ -83,11 +89,25 @@ public:
void SetPrime2(const Integer &q) {m_q = q;}
void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;}
virtual bool SupportsPrecomputation() const {return true;}
virtual void Precompute(unsigned int unused = 0) {PrecomputeTweakedRoots();}
virtual void Precompute(unsigned int unused = 0) const {PrecomputeTweakedRoots();}
virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation);
virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const;
protected:
void PrecomputeTweakedRoots() const;
protected:
Integer m_p, m_q, m_u;
mutable Integer m_pre_2_9p, m_pre_2_3q, m_pre_q_p;
mutable bool m_precompute;
};
//! RW
//! \class RW
//! \brief Rabin-Williams algorithm
struct RW
{
static std::string StaticAlgorithmName() {return "RW";}
@ -95,7 +115,8 @@ struct RW
typedef InvertibleRWFunction PrivateKey;
};
//! RWSS
//! \class RWSS
//! \brief Rabin-Williams signature scheme
template <class STANDARD, class H>
struct RWSS : public TF_SS<STANDARD, H, RW>
{